生產者與消費者案例
阿新 • • 發佈:2018-11-04
手頭有兩個人(也就是兩個類),一個做存操作,一個做取操作,並且只有當存完或者取完方可進行令一個操作。以此達到迴圈輸出的存取操作。
第一步:先寫測試生產者類與消費者類 和 執行緒操作Msg類 //生產者 public class Product implements Runnable{ private Msg msg = null; //執行緒操作物件 public Product (Msg msg){ super(); this.msg = msg; } @override public void run(){ for(int i=0;i<10;i++){ if(i%2==0){ try{ this.msg.set("男","胡明明"); }catch{ e.printStackTrace(); }else{ this.msg.set("女","肖體秀"); } } } } } //消費者 public class Consumer implements Runnable{ private Msg msg = null; public Consumer (Msg msg){ super(); this.msg = msg; } @override public void run(){ for(int i=0;i<10;i++){ try{ this.msg.get(); }catch{ e.printStackTrance(); } } } } //執行緒操作Msg類 public class Msg{ private String title; private String content; private boolearn flag = true;//true:生產者可以生產,不能取 false:消費者可以取,生產者不能生產 //多個執行緒訪問統一資源。要考慮到資料是否同步的問題,當執行緒進入睡眠或者等待其它執行緒會趁虛而入,所以在方法加上一把鎖 public synchrnoized void set (String title,String content){ if(this.flag == false){//存執行緒等待 System.out.println(Thread.currentThread().getName()+ "進入等待") super.wait(); } this.title = title; this.content = content; this.flag = false;//存完成,改變標識 System.out.println(Thread.currentThread.getNmae() + "睡眠,並喚醒睡眠或者等待的執行緒") super.notify();//喚醒第一個等待的執行緒(取) } public synchrnoized void get(){ if(this.flag == true){//取等待 super.wait(); } System.out.println(Thread.currentThread().getName() + this.title +"-----" + this.content) this.flag = false;//存完成,改變標識 super.notify();//喚醒第一個等待的執行緒(存) } public static void main(String[] args){ Msg msg = new Msg();//例項化物件 new Thread(msg,"存執行緒1")。start(); new Thread(msg,"存執行緒2")。start(); //new Thread(msg,"取執行緒")。start(); } } /** *實際上這個也很好理解,假設有兩個執行緒,存執行緒和取執行緒(兩個不同的操作類)被cpu呼叫,進入佇列,假 *設存執行緒先被執行**那麼,先走for迴圈第次存(同步,別的執行緒進不來)胡明明,當準備走第1次時,再次進 *行存的操作,發現存不了了,因為要存一次取一次,故將該執行緒進入睡眠狀態,也就數阻塞。所以在外面伺機*已久的取執行緒進來了,進行取得操作,並喚醒其它睡眠或者等待的執行緒(期間存執行緒可能已經被喚醒了,進行*了存的操作)。當再次準備繼續走迴圈時,同樣跟存一樣,也是必須一取一存才可以,由於識別符號的改變,故*取執行緒進入睡眠。以此類推 */
//當只有存取執行緒的時候確實是交易輸出,但是我加了一個存執行緒,進入死鎖。解析如下:
假設存1存2執行緒分別進入run方法,但是隻能有一個人才能做存操作,假設有幸是存1,那麼存1存完後,存方法被放開了,存1存2都有可能再次做存操作,但是,不管誰做存都做不了,要等到取做完才能做存,即會有兩個存執行緒進入等待狀態,隨後只有當取執行緒喚醒其中一個執行緒後才能進行存的操作,那麼它又將喚醒一個執行緒,那麼到底是喚醒存1還是存2呢?先不管,假設喚醒了存1,那存1又該喚醒誰呢?如果喚醒的是存2呢?那麼取執行緒也就只能睡著,即下一個存執行緒無法解放,兩個存執行緒就只能一直等待著,三個進入死鎖。