多執行緒通訊(二)生產者 消費者模式

2021-08-20 09:41:42 字數 3186 閱讀 3187

生產者/消費者模式其原理是基於wait/notify實現的。

通過**更能便於理解,廢話不多說,上**。

生成者和消費者一對一模式

生產者

public class producer 

public void buildproduct()

//生產產品並通知消費者

thread.sleep(1000);

system.out.println("生產者生產產品");

productobj.product = "我有產品";

obj.notify();

}} catch (interruptedexception e) }}

生產者執行緒

public class producerthread extends thread

@override

public void run()}}

消費者

public class consumer 

public void consumeproduct()

// 消費產品並通知生產者

thread.sleep(1000);

system.out.println("消費者消費產品");

productobj.product = "";

obj.notify();

}} catch (interruptedexception e)}}

消費者執行緒

public class consumerthread extends thread

@override

public void run()}}

產品容器

public class productobj
測試類

public class test2 

}

結果: 不停的在生產和消費產品。

生產者和消費者多對多模式

我們修改測試類,再修改下生產者和消費者類的列印方式,看下多對多的情況

生產者

public class producer 

public void buildproduct()

//生產產品並通知消費者

// thread.sleep(1000);

system.out.println(thread.currentthread().getname() + "*****=runnable");

productobj.product = "我有產品";

obj.notify();

}} catch (interruptedexception e) }}

消費者

public class consumer 

public void consumeproduct()

// 消費產品並通知生產者

// thread.sleep(1000);

system.out.println(thread.currentthread().getname() + "-----runnable");

productobj.product = "";

obj.notify();

}} catch (interruptedexception e)}}

測試類

public class test2 

//// producerthread producerthread = new producerthread(producer);

// producerthread.start();

// consumerthread consumerthread = new consumerthread(consumer);

// consumerthread.start();}}

這是結果

上面的結果中標紅的地方可以看出消費者0被喚醒後執行,消費產品,然後又競爭到鎖,進入wait狀態,然後消費者1競爭獲得鎖,但是這個時候是沒有產品的,但是也執行runnable了,可以看出,被喚醒的執行緒是從wait()方法後繼續執行的,也看出了**的不合理性,對消費者和生產者類稍作改動。

// 如果有產品,生產者等待

//if(stringutils.isnotblank(productobj.product))

// 如果沒有產品,消費者等待

//if(stringutils.isblank(productobj.product))

執行結果

這樣就不會出現上面描述的情況了,但是注意新**紅色框的地方,所有的執行緒都進入了等待狀態

,這種情況就是有機率發生的現象--假死

消費者的notify()方法喚醒的並不一定是生產者,也有可能是消費者

,而生產者的notify()喚醒也不一定是消費者,也有可能是生產者

,所以可能經過n次等待喚醒後可能所有執行緒全部是wait狀態,解決假死其實很簡單,就是在生產者和消費者中使用

notifyall()

方法,notifyall()

方法是用來喚醒所有等待執行緒的,這樣就不會出現假死現象了。

obj.notifyall();

部分結果截圖,結果沒有問題,如果消費者和生產者能交叉進行就更好了。下篇繼續改進。

下篇內容:多執行緒之通知/等待交叉進行

執行緒5 生產者消費者模式(執行緒通訊)

package com.thread.test 1 生產者生產出產品,給商店 緩衝區 2 商店把產品提供給消費者 1 需要三個角色,生產者,商店,消費者 2 涉及到多執行緒 3 涉及到執行緒安全 4 執行緒間通訊 class producer implements runnable override...

執行緒(六) 生產者消費者模式

為什麼要使用生產者消費者模式 什麼是生產者消費者模式 生產者消費模式是通過乙個容器來解決生產者和消費者的強耦合問題。生產者和消費這彼此之間不直接通訊,而通過阻塞佇列來進行通訊,所以生產者生產完資料之後不用等待消費者處理,直接扔給阻塞佇列,消費者不找生產者要資料,而是直接從阻塞佇列就相當於乙個緩衝區,...

java多執行緒初探(零)生產者消費者模式 執行緒通訊

測試類 package gcc.twothreadtransdata.producerandconsumer import org.slf4j.logger import org.slf4j.logge ctory 多個執行緒之間通訊 消費者生產者模式 多個生產者和消費者 流程 多個執行緒 生產者,...