JavaSE中多執行緒案例2(關於多執行緒通訊-等待與喚醒)
阿新 • • 發佈:2019-01-22
案例要求:
有一個抽獎池,該抽獎池中存放了獎勵的金額,該抽獎池用一個數組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();
}
}