# **
public# 輸出:class
public
static
void
main(string args)
}class
depot
public
synchronized
void produce(int
val)
int incre = (size + surplus) > capacity ? (capacity -size) : surplus;
size +=incre;
surplus -=incre;
system.out.printf("%s plan to produce (%d), actually produce (%d), depot size (%d) \n",
thread.currentthread().getname(), val, incre, size);
notify();}}
catch
(interruptedexception e)
}public
synchronized
void consume(int
val)
int desc = (size < surplus) ?size : surplus;
size -=desc;
surplus -=desc;
system.out.printf("%s plan to consume (%d), actutally consume (%d), depot size (%d) \n",
thread.currentthread().getname(), val, desc, size);
notify();}}
catch
(interruptedexception e)
}}class
producer
public
void produce(final
intval)
}.start();
}}class
consumer
public
void consume(final
intval)
}.start();}}
thread-0 plan to produce (60), actually produce (60), depot size (60)
thread-3 plan to consume (40), actutally consume (40), depot size (20)
thread-2 plan to produce (90), actually produce (80), depot size (100)
thread-1 plan to consume (100), actutally consume (100), depot size (0)
thread-2 plan to produce (90), actually produce (10), depot size (10)
# 有四個執行緒參與了這個過程,兩個生產者,兩個消費者
# 時隔多月,我們再來考慮一種業務場景,假設要求是,生產的時候的條件是:要麼全部生產,要麼全部不生產;消費的條件也是:要麼全部消費,要麼不消費;此時,實現的**可能如下:
public- 執行一下,你會發現倉庫中的數量會出現負的情況,如果你改變生產者和消費者的執行緒數,還有可能出現超過倉庫容量的情況,這該怎麼解決呢?class
common
for (int i = 0; i < 50; i++)
}}class
depot
public
synchronized
void produce(int
val)
size +=val;
system.out.printf("%s produce (%d), depot size (%d) \n", thread.currentthread().getname(), val, size);
notifyall();
} catch
(interruptedexception e)
}public
synchronized
void consume(int
val)
size -=val;
system.out.printf("%s consume (%d), depot size (%d) \n", thread.currentthread().getname(), val, size);
notifyall();
} catch
(interruptedexception e)
}}class
producer
public
void produce(final
intval)
}.start();
}}class
consumer
public
void consume(final
intval)
}.start();}}
- 其實解決方法很簡單,把wait()方法的判斷語句由if換成while即可;
- 我們來深究原因,以消費者為例,if的情況下,消費執行緒由wait狀態切換到執行狀態的時候,不再去判斷倉庫中的現有的儲存量是否滿足消費,此時該消費執行緒有可能由其他的消費執行緒喚醒,而其他的執行緒早已經把倉庫消費完了,該執行緒再去消費,倉庫自然就變成負的了。而while則不同,判斷條件為while時,每次消費者執行緒被喚醒,均會做一次判斷。
- 其實在jdk文件中,對這種情況已經作了強調說明, 如下圖所示
! 多讀官方文件,多讀原始碼! 手動笑哭。。。
生產者消費者問題
public class producer consumer class godown public godown int num public synchronized void produce int n catch interruptedexception e curr num n syste...
生產者 消費者問題
在學習程序互斥中,有個著名的問題 生產者 消費者問題。這個問題是乙個標準的 著名的同時性程式設計問題的集合 乙個有限緩衝區和兩類執行緒,它們是生產者和消費者,生產者把產品放入緩衝區,相反消費者便是從緩衝區中拿走產品。生產者在緩衝區滿時必須等待,直到緩衝區有空間才繼續生產。消費者在緩衝區空時必 須等待...
生產者 消費者問題
1 程序互斥問題 緩衝區b是臨界資源,程序p和c不能同時對b進行操作,即只能互斥的操作 2 程序同步問題 p不能往 滿 的的緩衝區b放產品,c不能從空的緩衝區獲得產品。當緩衝區滿時,c必須先於p執行,當緩衝區空時,p必須先於c執行 我們給出如下基於記錄型 二元 訊號量機制的解法 10 9 2013 ...