JavaSE中多线程案例2(关于多线程通信-等待与唤醒)

案例要求:

有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池用一个数组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();
	}
}


你可能感兴趣的:(JAVA基础)