wait、notify 實現生產者消費者

Java中的wait/notify/notifyAll可用來實現線程間通信,是Object類的方法,這三個方法都是native方法,是平臺相關的,常用來實現生產者/消費者模式。先來我們來看下相關定義:

  • wait() :調用該方法的線程進入WATTING狀態,只有等待另外線程的通知或中斷才會返回,調用wait()方法后,會釋放對象的鎖。
  • wait(long):超時等待最多long毫秒,如果沒有通知就超時返回。
  • notify() : 通知一個在對象上等待的線程,使其從wait()方法返回,而返回的前提是該線程獲取到了對象的鎖。
  • notifyAll():通知所有等待在該對象上的線程。

實例代碼

class ThreadA extends Thread{
    public ThreadA(String name) {
        super(name);
    }
    public void run() {
        synchronized (this) {
            try {                       
                Thread.sleep(1000); //  使當前線阻塞 1 s,確保主程序的 t1.wait(); 執行之后再執行 notify()
            } catch (Exception e) {
                e.printStackTrace();
            }           
            System.out.println(Thread.currentThread().getName()+" call notify()");
            // 喚醒當前的wait線程
            this.notify();
        }
    }
}
public class WaitTest {
    public static void main(String[] args) {
        ThreadA t1 = new ThreadA("t1");
        synchronized(t1) {
            try {
                // 啟動“線程t1”
                System.out.println(Thread.currentThread().getName()+" start t1");
                t1.start();
                // 主線程等待t1通過notify()喚醒。
                System.out.println(Thread.currentThread().getName()+" wait()");
                t1.wait();  //  不是使t1線程等待,而是當前執行wait的線程等待
                System.out.println(Thread.currentThread().getName()+" continue");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

LinkedBlockingQueue 實現

public class Consumer extends Thread {
    private Storage storage;
    public Consumer(Storage storage) {
        this.storage = storage;
    }
    @Override
    public void run() {
        while (true) {
            try {
                Storage.Goods goods = storage.goods.take();
                System.out.printf(String.valueOf(storage.goods.size())+"\\n");
                Thread.sleep(300);
                System.out.println("消費" + " " + goods.getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Producer extends Thread {

    private Storage storage;
    private int i = 0;
    public Producer(Storage storage) {
        this.storage = storage;
    }

    @Override
    public void run() {

        while (true) {
            try {
                storage.goods.put(new Storage.Goods("蘋果"+ i));
                Thread.sleep(100);
                i++;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

public class Storage {

    public static int MAX_COUNT = 5;    //容量為5

    public BlockingQueue<Goods> goods = new LinkedBlockingQueue<Goods>(MAX_COUNT);
    public Storage() {
    }
    public static class Goods {
        int id;
        String name;

        public Goods(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

public class TestThread {
    public static Object obj = new Object();

    public static void main(String[] args) throws InterruptedException {

        ExecutorService service = Executors.newCachedThreadPool();
        Storage storage = new Storage();
        Consumer consumer1 = new Consumer(storage);
        Consumer consumer2 = new Consumer(storage);
        Producer producer = new Producer(storage);

        service.submit(consumer1);
        service.submit(consumer2);
        service.submit(producer);

    }
}

參考博客
1.Java線程間通信之wait/notify
2. Java并發之生產者-消費者幾種實現

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 相關概念 面向對象的三個特征 封裝,繼承,多態.這個應該是人人皆知.有時候也會加上抽象. 多態的好處 允許不同類對...
    東經315度閱讀 2,005評論 0 8
  • 本文出自 Eddy Wiki ,轉載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,248評論 0 14
  • 擼了一下黃磊的深夜食堂,看了一下豆瓣評分似乎越來越低直逼2.0,原因是也許和原版的服裝太相似了
    糊吹吹閱讀 355評論 0 1
  • 粽子很忙。“粽子!”客廳里老爸在叫,粽子聞聲而去?!棒兆樱兆?,過來……”,房間里姐在叫粽子,粽子一聽,臉一轉,撒...
    4f1891572603閱讀 221評論 0 0