消費者與生產者模型--wait( )和notify( )方法
阿新 • • 發佈:2018-11-20
生產者與消費者
wait()方法
- 方法wait()的作用是使當前執行程式碼的執行緒進行等待,wait()方法是Object類的方法,該方法是用來將當前執行緒置入“預執行佇列”中,並且在wait()所在的程式碼處停止執行,直到接到通知或被中斷為止。
- wait()方法只能在同步方法中或同步塊中呼叫。如果呼叫wait()時,沒有持有適當的鎖,會丟擲異常
- wait()方法執行後,當前執行緒釋放鎖,執行緒與其它執行緒競爭重新獲取鎖。
notify()方法
-
方法notify()也要在同步方法或同步塊中呼叫,該方法是用來通知那些可能等待該物件的物件鎖的其它執行緒,對其發出通知notify,並使它們重新獲取該物件的物件鎖。如果有多個執行緒等待,則有執行緒規劃器隨機挑選出一個呈wait狀態的執行緒。
-
在notify()方法後,當前執行緒不會馬上釋放該物件鎖,要等到執行notify()方法的執行緒將程式執行完,也就是退出同步程式碼塊之後才會釋放物件鎖
class MyThread implements Runnable{ // private Object object; private boolean flag; public MyThread(Object object,boolean flag){ this.object = object; this.flag = flag; } public void waitMethod(){ synchronized (object){ System.out.println("wait方法開始。。"+Thread.currentThread().getName()); try{ object.wait(); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println("wait方法結束。。"+Thread.currentThread().getName()); } } public void notifyMethod(){ synchronized (object){ System.out.println("notify方法開始。。"+Thread.currentThread().getName()); object.notifyAll(); System.out.println("notify方法結束。。"+Thread.currentThread().getName()); } } public void run(){ if(flag){ this.waitMethod(); }else{ this.notifyMethod(); } } } class Test{ public static void main(String[] args) { Object object = new Object(); MyThread mythread = new MyThread(object,true); for(int i =0;i<10;i++){ Thread thread1 = new Thread(mythread,"wait執行緒"+i); thread1.start(); } MyThread mythread2 = new MyThread(object,false); Thread thread3 = new Thread(mythread2); thread3.start(); } } 從結果上來看第一個執行緒執行的是一個waitMethod方法,該方法裡面有個死迴圈並且使用了wait方法進入等待狀態 將釋放鎖,如果這個執行緒不被喚醒的話將會一直等待下去,這個時候第二個執行緒執行的是notifyMethod方法,該方 法裡面執行了一個喚醒執行緒的操作,並且一直將notify的同步程式碼塊執行完畢之後才會釋放鎖然後繼續執行wait結束 列印語句
notifyAll()方法
- 使用notifyAll()方法喚醒所有等待執行緒
class MyThread implements Runnable{ private Object object; private boolean flag; public MyThread(Object object,boolean flag){ this.object = object; this.flag = flag; } public void waitMethod(){ synchronized (object){ System.out.println("wait方法開始。。"+Thread.currentThread().getName()); try{ object.wait(); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println("wait方法結束。。"+Thread.currentThread().getName()); } } public void notifyMethod(){ synchronized (object){ System.out.println("notify方法開始。。"+Thread.currentThread().getName()); object.notifyAll(); System.out.println("notify方法結束。。"+Thread.currentThread().getName()); } } public void run(){ if(flag){ this.waitMethod(); }else{ this.notifyMethod(); } } } class Test{ public static void main(String[] args) { Object object = new Object(); MyThread mythread = new MyThread(object,true); for(int i =0;i<10;i++){ Thread thread1 = new Thread(mythread,"wait執行緒"+i); thread1.start(); } MyThread mythread2 = new MyThread(object,false); Thread thread3 = new Thread(mythread2); thread3.start(); } }
生產者與消費者模型
- 生產者與消費者開頭已經介紹過了,生產者與消費者一般需要第三者來解耦的,所以現在就模擬一個簡單的商品的生產者與消費者,由生產者執行緒生產出一個商品之後將由消費者執行緒開始消費
//商品類
class Goods{
private String goodName;
private int count;
//生產商品方法
public synchronized void set(String goodName){
//while
if(count > 0){
System.out.println("商品還有吶");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.goodName = goodName;
this.count++;
System.out.println(Thread.currentThread().getName()+"生產"+goodName+toString());
//喚醒等待消費的庫存
notify();
//notifyAll();
}
//消費商品方法
public synchronized void get(){
//while
if(count == 0){
System.out.println("賣完啦~");
try {
//等待商品生產
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.count--;
System.out.println(Thread.currentThread().getName()+"消費"+goodName+toString());
//喚醒生產者生產
notify();
//notifyAll();
}
@Override
public String toString() {
return "Goods{" +
"goodName='" + goodName + '\'' +
", count=" + count +
'}';
}
}
//生產執行緒
class Producer implements Runnable{
private Goods goods;
public Producer(Goods goods){
this.goods = goods;
}
public void run(){
//while(true){
goods.set("牛排");
//}
}
}
//消費執行緒
class Consumer implements Runnable{
private Goods goods;
public Consumer(Goods goods){
this.goods = goods;
}
public void run(){
//while(true){
goods.get();
//}
}
}
class Test{
public static void main(String[] args) {
Goods good = new Goods();//同一個物件
Thread mythread = new Thread(new Producer(good),"生產者");
Thread mythread1 = new Thread(new Consumer(good),"消費者");
mythread.start();
mythread1.start();
// List<Thread> list = new ArrayList<>();
// for (int i = 0;i<10;i++){
// Thread thread new Thread(new Consumer(good),"xiaofeiz"+i);
// }
}
}