案例要求:
有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池用一个数组int[] arr = {10,5,20,50,100,200,500,800,2,80,300};
创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”,随机从arr数组中获取奖项元素并打印在控制台上,格式如下:
抽奖箱1 又产生了一个 10 元大奖
抽奖箱2 又产生了一个 100 元大奖
//.....
/*
* 定义多线程的共享数据-奖池
* 设置标记位来让两个线程交替输出
*/
public class RewardPool {
public int[] arr = {10,5,20,50,100,200,500,800,2,80,300};
public boolean flag = true;
}
/*
* 定义抽奖箱1线程,重写构造器,里面传入共享数据类的对象,作为对象锁,保证锁的唯一性
* 抽奖箱1线程优先输出,且输出一次后,使用锁对象调用wait()方法,将标记位取反,再调用notify()唤醒抽奖箱2线程
*/
public class RewardBox1 implements Runnable{
public RewardPool rp;
public RewardBox1(RewardPool rp) {
this.rp = rp;
}
private Random ran = new Random();
public void run() {
while(true) {
synchronized(rp) {
//flag为true表示抽奖箱1线程应该执行,否则表示2应该执行
if(!rp.flag) {
try {
rp.wait();
}catch(Exception ex) {}
}
int ranNum = ran.nextInt(11);
System.out.println("抽奖箱1 又产生了一个" + rp.arr[ranNum] + "元大奖");
rp.flag = false;
rp.notify();
}
}
}
}
/*
* 定义抽奖箱2线程,重写构造器,里面传入共享数据类的对象,作为对象锁,保证锁的唯一性
* 抽奖箱2线程输出一次后,使用锁对象调用wait()方法,将标记位取反,再调用notify()唤醒抽奖箱1线程
*/
public class RewardBox2 implements Runnable {
public RewardPool rp;
public RewardBox2(RewardPool rp) {
this.rp = rp;
}
private Random ran = new Random();
public void run() {
while(true) {
synchronized(rp) {
if(rp.flag) {
try {
rp.wait();
}catch(Exception ex) {}
}
int ranNum = ran.nextInt(11);
System.out.println("抽奖箱2 又产生了一个" + rp.arr[ranNum] + "元大奖");
rp.flag = true;
rp.notify();
}
}
}
}
/*
* 定义抽奖测试类,创建唯一一个共享数据类的对象
* 创建两个线程任务类对象,创建两个线程,启动线程
*/
public class RewardDemo {
public static void main(String[] args) {
RewardPool rp = new RewardPool();
RewardBox1 rb1 = new RewardBox1(rp);
RewardBox2 rb2 = new RewardBox2(rp);
Thread tb1 = new Thread(rb1);
Thread tb2 = new Thread(rb2);
tb1.start();
tb2.start();
}
}