第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

為什么這個多線程程序會陷入無限循環(huán)?

為什么這個多線程程序會陷入無限循環(huán)?

慕碼人8056858 2021-11-03 16:49:07
下面的程序是一個簡單的線程程序。由于某種我無法想象的原因,它在兩個線程中同時陷入了生產(chǎn)()和消費()方法的無限循環(huán)中。它產(chǎn)生幾次輸出,然后在控制臺上沒有輸出。所以我認(rèn)為它陷入了循環(huán)。我的問題是,由于循環(huán)取決于valueSetItem 類的同一對象的標(biāo)志值,valueSet因此不能同時為真和假。因此,produce() 或 cosume() 方法的循環(huán)都應(yīng)該為 false,并且輸出的打印應(yīng)該繼續(xù)。但這里不會發(fā)生這種情況。那么,如果條件取決于一次只能取真或假的標(biāo)志變量,為什么它會卡在 while 循環(huán)中呢?class Item{    boolean valueSet = false ;     int item = 0 ;     public  void consume(){        while(!valueSet) ;        System.out.println("Consumed : "  + item ) ;         valueSet = false ;    }    public  void produce(int n ){        while(valueSet);        item = n ;        System.out.println("Produced : "  + item ) ;         valueSet = true ;    } }class Producer implements Runnable{ Item item ; Producer(Item itemobj){     item = itemobj ;  } public void run(){     while(true){         System.out.println("\nProducing ....") ;      item.produce((int)Math.random()*100) ;      } }}class Consumer implements Runnable{    Item item  ;    Consumer(Item itemobj){item = itemobj ; }    public void run(){        while(true){            System.out.println("\nConsuming !") ;        item.consume() ;         }    }}class Main{    public static void main(String[] args) {        Item item = new Item() ;        Thread consumer = new Thread(new Consumer(item)) ;         Thread producer = new Thread(new Producer(item)) ;        System.out.println("\nStarted producer and consumer threads : ") ;         consumer.start() ;         producer.start() ;     }}更新 :當(dāng)while(valueSet)一個線程卡在無限循環(huán)中時,不應(yīng)該while(!valuSet)跳出循環(huán)并翻轉(zhuǎn)valueSet? 這會反過來導(dǎo)致while(valueSet)跳出循環(huán)嗎?根據(jù)某些答案,似乎在while(valueSet)卡住時,另一個線程以某種方式無法訪問valueSet。我不明白這是怎么回事。請解釋你的答案。我看到使用volatileforvalueSet會修復(fù)它,但我無法理解如何不使用它。即使它依賴于一個valueSet不能同時為真和假的標(biāo)志,它也會導(dǎo)致無限循環(huán)。
查看完整描述

3 回答

?
嚕嚕噠

TA貢獻1784條經(jīng)驗 獲得超7個贊

基本上,您在這里嘗試做的是valueSet用作布爾標(biāo)志來同步Consumer和Producer-- 使它們依次工作。真的,valueSet只能在一瞬間是真的或假的;然而,這不是兩個線程(消費者和生產(chǎn)者)如何看待它。


我們知道在 Java 中,對象存儲在堆上;那就是所謂的主存。但是,對于每個線程,出于性能考慮,對所用對象的引用都保存在特定于線程的緩存中。如在這里,Producer和Consumer共享一個Item被存儲在堆上對象; 該字段item.valueSet可能被每個線程緩存。


 _______________    ______________  

 |   Consumer    |  |   Producer   |  

 |   _________   |  |   _________  |  

 |  |         |  |  |  |         | |  

 |  | Cache1  |  |  |  |  Cache2 | |  

 |  | valueSet|  |  |  | valueSet| |

 |  |_________|  |  |  |_________| |  

 |_______________|  |______________|

           | |              | |

           | |              | |

          _|_|______________|_|__

         |                       |

         |      MAIN MEMORY      | 

         |      valueSet         | 

         |_______________________|

例如,當(dāng)Consumer更改valueSet為 時false,它可能會也可能不會將新值刷新到主內(nèi)存;類似地,當(dāng)Producer檢查時valueSet,它可能會也可能不會嘗試從主內(nèi)存中讀取最新值。這就是volatile關(guān)鍵字發(fā)揮作用的地方。當(dāng)您設(shè)置valueSet為 時volatile,它確保兩個線程向/從主內(nèi)存寫入/讀取最新值。


請注意,上面的總結(jié)基本上被稱為JVM 內(nèi)存模型。它是一組規(guī)則,用于定義多線程情況下 JVM 的行為。


如果您嘗試更改代碼的以下部分:


    **volatile** boolean valueSet = false ; 

    **volatile** int item = 0 ;

    ...

    item.produce((int)(Math.random()*100)) ; // added parenthesis

您將看到以下輸出:


Started producer and consumer threads : 


Consuming !


Producing ....

Produced : 83


Producing ....

Consumed : 83


Consuming !

Produced : 54


Producing ....

Consumed : 54


Consuming !

Produced : 9


Producing ....

Consumed : 9


Consuming !

Produced : 23


Producing ....

Consumed : 23


查看完整回答
反對 回復(fù) 2021-11-03
?
阿晨1998

TA貢獻2037條經(jīng)驗 獲得超6個贊

首先,您需要創(chuàng)建共享變量volatile。

允許線程將其局部變量放在寄存器中,所以是的,一個線程可以將其valueSet視為 false,而另一個線程可以將其視為true. 同時。使變量volatile強制每次都從內(nèi)存中讀取。

但是,這并不能保證代碼沒有其他問題。同步可能很棘手。但是研究volatile以克服最可能的原因。


查看完整回答
反對 回復(fù) 2021-11-03
?
桃花長相依

TA貢獻1860條經(jīng)驗 獲得超8個贊

ü應(yīng)該設(shè)置valueSetvolatile使兩個線程變量可見。


查看完整回答
反對 回復(fù) 2021-11-03
  • 3 回答
  • 0 關(guān)注
  • 275 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號