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

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

當(dāng)Java LinkedBlocking Queue只有一個元素時,如果同時放置和取出會發(fā)生什么?

當(dāng)Java LinkedBlocking Queue只有一個元素時,如果同時放置和取出會發(fā)生什么?

繁華開滿天機(jī) 2019-04-04 22:15:48
LinkedBlocking Queue有兩個鎖,一個用于put,一個用于take。當(dāng)隊列的大小為1時,我認(rèn)為兩個線程可以同時鎖定和操作隊列,這將導(dǎo)致未定義的行為。我錯了嗎?// method put:                             // method take:             // put lock                                 // take lock  putLocK.lockInterruptibly();              takeLock.lockInterruptibly();                        ...                                       ...  while(count.get() == capacity){           while(count.get() == 0){    notFull.await();                          notEmpty.await();  }                                         }  enqueue(node);                            x = dequeue();// method enqueue:                           // method dequeue:   last = last.next = node;                 Node<E> h = head;      ...                                       Node<E> first = h.next;                                            h.next = h;                                                    head = first;                                                 E x = first.item;                                                 first.item = null;                                               return x;當(dāng)隊列中只有一個項目時,顯然可以將線程和線程鎖定,因此它們將分別在方法入隊和出隊中執(zhí)行代碼。我的意思是如果線程進(jìn)入方法出列,在所有指針修改后,不會與enqueue中的代碼沖突?這里的鏈接說“但是當(dāng)隊列為空時,無法避免爭用,因此需要額外的代碼來處理這種常見的”邊緣“情況”在Java中,BlockingQueue是否完全是線程安全的
查看完整描述

3 回答

?
慕碼人2483693

TA貢獻(xiàn)1860條經(jīng)驗 獲得超9個贊

BlockingQueue 的javadoc(LinkedBlockingQueue的超類)聲明:

BlockingQueue實現(xiàn)是線程安全的。所有排隊方法都使用內(nèi)部鎖或其他形式的并發(fā)控制以原子方式實現(xiàn)其效果。

“原子地”一詞意味著如果兩個操作(例如a put和a take)同時發(fā)生,那么實現(xiàn)將確保它們根據(jù)合同行為。效果會仿佛put之前發(fā)生get,反之亦然。這也適用于邊緣情況,例如具有一個元素的隊列示例。

實際上,由于put并且get正在阻塞操作,因此兩個操作的相對順序無關(guān)緊要。與offerpolladdremove順序的事,但你無法控制它。


請注意,上述內(nèi)容完全基于javadoc所說的內(nèi)容。假設(shè)我已正確解釋了javadoc,那么它適用于所有1個 BlockingQueue實現(xiàn),無論它們是使用一個還是兩個鎖......或者根本不使用。如果BlockingQueue實現(xiàn)不像上面那樣,那就是一個錯誤!

1 - 正確實現(xiàn)API的所有實現(xiàn)。這應(yīng)該涵蓋所有Java SE類。


查看完整回答
反對 回復(fù) 2019-05-15
?
慕絲7291255

TA貢獻(xiàn)1859條經(jīng)驗 獲得超6個贊

put 實施一個 LinkedBlockingQueue

public void put(E e) throws InterruptedException {
    // some lock and node code

    // the part that matters here
    try {

        while (count.get() == capacity) {
            notFull.await();
        }

        // put the item in the queue.
    } finally {
        // not important here
    }}

基本上,在put調(diào)用線程wait中,容量小于最大持續(xù)時間。

即使將值放在隊列上的線程抓取與take線程不同的鎖,它也會等待將其添加到隊列中,直到隊列未滿。

take有一個類似的實現(xiàn),notEmpty而不是notFull。

分享編輯


查看完整回答
反對 回復(fù) 2019-05-15
?
慕哥6287543

TA貢獻(xiàn)1831條經(jīng)驗 獲得超10個贊


經(jīng)過2天的搜索,我終于明白了...當(dāng)隊列中只有一個項目時,根據(jù)LinkedBlocking Queue的設(shè)計,實際上有兩個節(jié)點:虛擬頭和真實項目(同時最后指向它)。確實,put thread和take thread都可以獲得鎖定,但是它們會修改隊列的不同部分。


Put線程會調(diào)用


last = last.next = node; // last points to the only item in queue

拿線程會打電話


Node<E> h = head;

Node<E> first = h.next;  // first also points to the only item in queue

h.next = h; 

head = first;

E x = first.item;

first.item = null;

return x;

這兩個線程的交集是最后指向put線程以及在線程中首先指向的線程。請注意,put thread僅修改last.item并且take thread僅修改first.next。雖然這兩個線程修改了同一個對象實例,但它們會修改它的不同成員,并且不會導(dǎo)致任何線程沖突。


查看完整回答
反對 回復(fù) 2019-05-15
  • 3 回答
  • 0 關(guān)注
  • 982 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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