1. 程式人生 > 其它 >wait/notify應用舉例實現生產者和消費者通訊模型

wait/notify應用舉例實現生產者和消費者通訊模型

技術標籤:Javajava多程序

下面,在不考慮實用性等前提下,我們會實現一個最簡單的生產者、消費者模型,僅僅只用來理解wait/notify的機制。

在這個例子裡,將啟動一個生產者執行緒、一個消費者執行緒。生產者檢測到有產品可供消費時,通知消費者(notify)進行消費,同時自己進入等待狀態(wait),如果檢測到沒有產品可供消費,則進行生產。
消費者檢測到有產品可供消費時,則進行消費,消費結束沒通知生產者進行生產,如果檢測到沒有產品可供消費,自然也通知生產者進行生產。
也就是說,生產者執行緒和消費者執行緒會互相等待和互相通知。他們會爭奪同一個物件obj的鎖,實現執行緒之間的通訊

Product類:

public class Product {
    private static Integer count = 0;
 
    public static void add() {
        count++;
    }
 
    public static void delete() {
        count--;
    }
 
    public static Integer getCount(){
        return count;
    }
}

Produce類:

public class Produce implements Runnable {
 
    private
Object object; public Produce(Object object) { this.object = object; } @Override public void run() { synchronized (object) { System.out.println("++++ 進入生產者執行緒"); System.out.println("++++ 產品數量:" + Product.getCount()); while
(true) { try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } if (Product.getCount() <= 0) { System.out.println("++++ 開始生產!"); Product.add(); System.out.println("++++ 生產後產品數量:" + Product.getCount()); }else { try { // 通知消費者進行消費,自己進入等待 object.notify(); object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }

Consume類:

import java.util.concurrent.TimeUnit;
 
public class Consume implements Runnable {
 
    private Object object;
 
    public Consume(Object object) {
        this.object = object;
    }
 
    @Override
    public void run() {
        synchronized (object) {
            System.out.println("---- 進入消費者執行緒");
            System.out.println("---- 當前產品數量:" + Product.getCount());
            // 判斷條件是否滿足(有沒有產品可以消費),若不滿足則等待
            while (true) {
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (Product.getCount() <= 0) {
                    try {
                        System.out.println("---- 沒有產品,進入等待");
                        // 通知生產者生產,自己進入等待
                        object.notify();
                        object.wait();
                        System.out.println("---- 結束等待,開始消費");
                        Product.delete();
                        System.out.println("---- 消費後產品數量:" + Product.getCount());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("---- 已有產品,直接消費");
                    Product.delete();
                    System.out.println("---- 消費後產品數量:" + Product.getCount());
                }
 
 
            }
 
        }
    }
}

測試主類

public class ThreadTest {
 
    static final Object obj = new Object();
 
 
    public static void main(String[] args) throws Exception {
 
        Thread consume = new Thread(new Consume(obj), "Consume");
        Thread produce = new Thread(new Produce(obj), "Produce");
        // 先啟動消費者
        consume.start();
        produce.start();
 
 
    }
 
 
}

在這裡插入圖片描述

程式會一直執行下去。