1. 程式人生 > >JavaSE中多執行緒案例2(關於多執行緒通訊-等待與喚醒)

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();
	}
}