1. 程式人生 > >Java——設定執行緒等待與執行緒喚醒

Java——設定執行緒等待與執行緒喚醒

//執行緒間的通訊:執行緒的任務不同,但是執行緒操作的資料相同
/*
wait(),notify(),notifyAll()必須用在同步中,因為同步中才有鎖
指明讓持有哪個鎖的執行緒去等待或被喚醒
*/
//還是上次的例子,實現存一個輸出一個,而不是輸出一大堆

//描述資料
class Res{
    String name;
    String sex;
    //加一個flag標記,false表示沒有資料
    //false即可以存,存完之後,flag改為true,喚醒輸出執行緒,然後放棄CPU,讓他等待
    //等輸出資料的任務輸出一組資料後,把輸入的執行緒喚醒,把flag改為false,
    //然後放棄CPU,即讓其也進入等待狀態,再讓輸入執行緒接著存
boolean flag = false; } //利用建構函式,把同一個res傳給輸入任務和輸出任務 //即保證了兩者為同一個res //描述輸入任務 class Input implements Runnable{ private Res res; //兩個執行緒同一把鎖才能實現互相排斥,所以不用obj鎖,用res當鎖 //private Object obj = new Object(); public Input(Res res){ this.res = res; } public void run(){ int i = 1
; while(true){ //下面的if條件語句和else中的語句存在安全問題 //因為是兩句話,中間有可能被其他執行緒搶走CPU //所以在輸出的時候會有“張三....女”這樣的輸出 //解決四路:存資料的時候不能輸出 //方法,對t1和t2兩個執行緒進行同步操作,但是要保證用 //同一把鎖,所以不能再用obj鎖 /*if(i==1){ res.name = "張三"; res.sex = "男"; }else{ res.name = "李四"; res.sex = "女"; }*/
synchronized(res){ //先判斷該不該存 //如果flag是true,說明有資料,不能輸入,讓其等待 //wait()方法必須用在同步當中,因為同步當中才有鎖 if(res.flag){ //wait前加res的原因,因為有可能有其他執行緒,其他鎖 //通過鎖來執行,讓哪個執行緒來等待 //等待的執行緒會放棄鎖 try{res.wait();}catch(InterruptedException e){e.printStackTrace();} } //如果是false,輸入資料 if(i==1){ res.name = "張三"; res.sex = "男"; }else{ res.name = "李四"; res.sex = "女"; } //輸入完成後將flag標誌改為true,意思是可以輸出了 res.flag = true; res.notify();//喚醒輸出執行緒,允許空喚醒,即沒有需要被喚醒的也可以 } //1 0切換 i = (i+1)%2; } } } //描述輸出任務 class Output implements Runnable{ private Res res; public Output(Res res){ this.res = res; } public void run(){ while(true){ synchronized(res){ //判斷該不該輸出 //如果flag是false,則沒有資料可以輸出,讓其等待 if(!res.flag){ try{res.wait();}catch(InterruptedException e){e.printStackTrace();} } System.out.println(res.name+"...."+res.sex); //把flag改為false,意思是可以進行輸入了 res.flag = false; //喚醒輸入程序 res.notify(); } } } } class test{ public static void main(String[] args){ //建立資源物件 Res res = new Res(); //輸入任務和輸出任務用同一個物件,即相同的資源 //建立輸入任務 Input in = new Input(res); //建立輸出任務 Output out = new Output(res); //建立輸入執行緒 Thread t1 = new Thread(in); //建立輸出執行緒 Thread t2 = new Thread(out); t1.start(); t2.start(); } }