Java多线程抽奖
2018-09-09 本文已影响0人
xuchengsheng
习题一
有一个抽奖池,池子里面放了固定的金额
int[] prizePool = {100,200,300,400,500,600,700,800,900,1000,1100};
此时有两个抽奖箱分别为("抽奖箱1","抽奖箱2") 并且每个箱子要轮流抽奖
列(抽奖箱1->抽奖箱2->抽奖箱1->抽奖箱2)依次类推直到抽取完毕。
package com.superxu.practice;
public class ChouJiangPool {
/** 抽奖箱1 */
public String boxOne="抽奖箱1";
/** 抽奖箱2 */
public String boxTwo="抽奖箱2";
/** 奖池金额 */
public int[] prizePool = {100,200,300,400,500,600,700,800,900,1000,1100};
/** 奖池总数 */
public int num = prizePool.length;
/** 已经使用过的 */
public boolean[] usePrize=new boolean[num];
/** 当前线程抽奖箱 */
public String currentThreadBox=boxOne;
}
package com.superxu.practice;
import java.util.Random;
public class ChouJiangMain {
public static void main(String[] args) {
ChouJiangPool pool=new ChouJiangPool();
/** 抽奖箱1 */
Thread thread1 = new Thread(new ChouJiangBox(pool));
thread1.setName(pool.boxOne);
thread1.start();
/** 抽奖箱2 */
Thread thread2 = new Thread(new ChouJiangBox(pool));
thread2.setName(pool.boxTwo);
thread2.start();
}
public static class ChouJiangBox implements Runnable{
ChouJiangPool pool;
public ChouJiangBox(ChouJiangPool pool) {
this.pool=pool;
}
@Override
public void run() {
/** 是否还有剩余奖品可以抽取 */
while (pool.num>0) {
synchronized (pool) {
/** 获取抽奖箱名称 */
String boxName = Thread.currentThread().getName();
/** 查看当前线程是否是同一个 */
if(!pool.currentThreadBox.equals(boxName)) {
try {
/** 如果没有轮到当前抽奖箱,则进入线程等待 */
pool.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/** 随机从线程中抽取奖品 */
Random r=new Random();
int index = r.nextInt(pool.prizePool.length);
/** 查看是否抽取的奖品已使用 */
if(!pool.usePrize[index]) {
/** 从池子总获取一个奖品 */
int prize=pool.prizePool[index];
/** 奖品数量减一 */
pool.num-=1;
/** 标记已经使用的奖品 */
pool.usePrize[index]=true;
/** 切换下一个抽奖箱 */
if(boxName.equals(pool.boxOne)) {
pool.currentThreadBox=pool.boxTwo;
}else if(boxName.equals(pool.boxTwo)){
pool.currentThreadBox=pool.boxOne;
}
System.out.println(Thread.currentThread().getName()+"获得奖品"+prize);
/** 通知下个抽奖箱抽奖 */
pool.notifyAll();
}
}
}
}
}
}
wait:使持有该对象的线程把该对象的控制权交出去,然后处于等待状态
notify:通知某个正在等待这个对象的控制权的线程可以继续运行
notifyAll: 会通知所有等待这个对象控制权的线程继续运行