亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

多生產者和消費者多線程 Java 未按預期工作

多生產者和消費者多線程 Java 未按預期工作

弒天下 2023-08-23 10:36:38
我正在研究 Java 的生產者-消費者問題的多個生產者和消費者用例。代碼在github上。相同的實現適用于單個生產者消費者用例,但對于多個生產者消費者用例表現得很奇怪。我對輸出有一些疑問:一開始,所有生產者和一個消費者都擁有鎖:Producer t1 has lockt5 produced 1, integerQueue: [1]Producer t5 notifiedAll我認為所有線程都應該競爭鎖,并且應該最多有一個線程一直擁有鎖?所有生產者都共享鎖嗎?當生產者線程 t1 持有鎖時,消費者線程 t5 如何獲得鎖?運行一段時間后,又出現了一個奇怪的現象:Producer t5 has lockt5 produced 10, integerQueue: [8, 9, 10]Producer t5 notifiedAllProducer t5 has lockt5 produced 11, integerQueue: [8, 9, 10, 11]Producer t5 notifiedAllConsumer t8 has lockt8 consumed 8, integerQueue: [9, 10, 11]Consumer t8 notified AllConsumer t8 has lockt8 consumed 9, integerQueue: [10, 11]Consumer t8 notified All似乎除了一個生產者和消費者之外的所有線程都已死亡,并且這兩個線程正在彼此之間切換鎖。為什么會發生這種情況?所有其他生產者和消費者發生了什么?任何幫助是極大的贊賞。
查看完整描述

1 回答

?
慕后森

TA貢獻1802條經驗 獲得超5個贊

您正在使用可運行對象的單個實例Producer5,并將其多次提交給執行服務。


    Producer5 producer = new Producer5(queue, maxCapacity);

    pool.execute(producer);

    pool.execute(producer);

    pool.execute(producer);

    pool.execute(producer);

    pool.execute(producer);

因此,threadName該單個實例中的字段Producer5將被覆蓋多次并且沒有用(它將不再打印出實際正在運行的線程的名稱,此外,它需要被volatile多個線程正確更新 -對于正確的一些定義)。


  System.out.println(String.format("\nProducer %s has lock",

    threadName // this will be the name of the last thread that entered `run`, 

              // they all share the same instance 

  )); 

Runnable如果同一實例包含可變狀態,請勿重復使用該實例。為每個執行線程創建一個單獨的實例。


當生產者線程 t1 持有鎖時,消費者線程 t5 如何獲得鎖?


仍然是線程 t1 運行此代碼,但該threadName字段同時已由線程 t5 更新。高度誤導性的輸出。


似乎除了一個生產者和消費者之外的所有線程都已死亡,并且這兩個線程正在彼此之間切換鎖。


線程都仍然處于活動狀態,但只有兩個threadName字段存在,線程輪流更新它們(在方法的頂部run),最終確定某個值。所有線程現在只打印該值。


查看完整回答
反對 回復 2023-08-23
  • 1 回答
  • 0 關注
  • 172 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號