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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

帶翻轉(zhuǎn)緩沖器的無鎖容器

帶翻轉(zhuǎn)緩沖器的無鎖容器

夢(mèng)里花落0921 2022-08-03 12:59:56
對(duì)于我的一個(gè)必須支持并發(fā)讀取和寫入的項(xiàng)目,我需要一個(gè)能夠緩沖項(xiàng)的容器,直到使用者一次獲取每個(gè)當(dāng)前緩沖的項(xiàng)。由于生產(chǎn)者應(yīng)該能夠生成數(shù)據(jù),而不管消費(fèi)者是否讀取當(dāng)前緩沖區(qū),我提出了一個(gè)自定義實(shí)現(xiàn),在的幫助下,將每個(gè)條目添加到支持中,直到執(zhí)行翻轉(zhuǎn),這會(huì)導(dǎo)致當(dāng)前條目被返回,同時(shí)存儲(chǔ)具有空隊(duì)列和元數(shù)據(jù)的新條目以原子方式存儲(chǔ)在該中。AtomicReferenceConcurrentLinkedQueueAtomicReference我想出了一個(gè)解決方案,例如public class FlippingDataContainer<E> {  private final AtomicReference<FlippingDataContainerEntry<E>> dataObj = new AtomicReference<>();  public FlippingDataContainer() {    dataObj.set(new FlippingDataContainerEntry<>(new ConcurrentLinkedQueue<>(), 0, 0, 0));  }  public FlippingDataContainerEntry<E> put(E value) {    if (null != value) {      while (true) {        FlippingDataContainerEntry<E> data = dataObj.get();        FlippingDataContainerEntry<E> updated = FlippingDataContainerEntry.from(data, value);        if (dataObj.compareAndSet(data, updated)) {          return merged;        }      }    }    return null;  }  public FlippingDataContainerEntry<E> flip() {    FlippingDataContainerEntry<E> oldData;    FlippingDataContainerEntry<E> newData = new FlippingDataContainerEntry<>(new ConcurrentLinkedQueue<>(), 0, 0, 0);    while (true) {      oldData = dataObj.get();      if (dataObj.compareAndSet(oldData, newData)) {        return oldData;      }    }  }  public boolean isEmptry() {    return dataObj.get().getQueue().isEmpty();  }}由于其他線程在此線程可以執(zhí)行更新之前更新值可能會(huì)導(dǎo)致可能的重試,因此我需要在每次寫入嘗試時(shí)復(fù)制實(shí)際隊(duì)列,否則即使原子引用無法更新,也會(huì)將條目添加到共享隊(duì)列中。因此,只需將值添加到共享隊(duì)列中,就可能導(dǎo)致值條目多次添加到隊(duì)列中,而實(shí)際上它只應(yīng)出現(xiàn)一次。雖然與復(fù)制隊(duì)列的代碼相比,這允許運(yùn)行測(cè)試的速度快10倍以上,但它也經(jīng)常無法通過消耗測(cè)試,因?yàn)楝F(xiàn)在,在消費(fèi)者線程翻轉(zhuǎn)隊(duì)列并處理數(shù)據(jù)之后,可能會(huì)立即將值元素添加到隊(duì)列中,因此并非所有項(xiàng)目似乎都被消耗了?,F(xiàn)在的實(shí)際問題是,是否可以避免復(fù)制后備隊(duì)列以獲得性能提升,同時(shí)仍然允許使用無鎖算法原子地更新隊(duì)列的內(nèi)容,從而避免中途丟失一些條目?
查看完整描述

2 回答

?
三國(guó)紛爭(zhēng)

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超7個(gè)贊

首先,讓我們陳述一個(gè)顯而易見的事實(shí) - 最好的解決方案是避免編寫任何此類自定義類。也許像java.util.concurrent.LinkedTransferQueue這樣簡(jiǎn)單的東西也可以工作,并且不那么容易出錯(cuò)。如果 a 不起作用,那么 LMAX 干擾器或類似的東西呢?您是否看過現(xiàn)有的解決方案?LinkedTransferQueue

如果你仍然需要/想要一個(gè)自定義解決方案,那么我有一個(gè)稍微不同的方法的草圖,一個(gè)可以避免復(fù)制的方法:

這個(gè)想法是讓操作圍繞一些原子變量旋轉(zhuǎn),試圖設(shè)置它。如果線程設(shè)法設(shè)置了它,那么它將獲得對(duì)當(dāng)前隊(duì)列的獨(dú)占訪問權(quán)限,這意味著它可以追加到它。追加后,它會(huì)重置原子變量以允許其他線程追加。它基本上是一個(gè)旋轉(zhuǎn)鎖。這樣,線程之間的爭(zhēng)用就會(huì)在追加到隊(duì)列之前發(fā)生,而不是在追加到隊(duì)列之后。put


查看完整回答
反對(duì) 回復(fù) 2022-08-03
?
MYYA

TA貢獻(xiàn)1868條經(jīng)驗(yàn) 獲得超4個(gè)贊

我需要在每次寫入嘗試時(shí)復(fù)制實(shí)際隊(duì)列

你的想法聽起來像RCU(https://en.wikipedia.org/wiki/Read-copy-update)。Java被垃圾回收通過為您解決解除分配問題使RCU變得更加容易(我認(rèn)為)。

如果我從你的問題的快速瀏覽中正確理解,你的“讀者”實(shí)際上想為自己“聲稱”容器的整個(gè)當(dāng)前內(nèi)容。這也使它們有效地成為編寫者,但是它們不是讀取+復(fù)制,而是可以構(gòu)造一個(gè)空容器,并原子地交換頂級(jí)引用以指向該容器。(因此,聲明舊容器進(jìn)行獨(dú)占訪問。

RCU的一大好處是容器數(shù)據(jù)結(jié)構(gòu)本身不必到處都是原子的。一旦你有對(duì)它的引用,就沒有其他人在修改它。


唯一棘手的部分是當(dāng)作家想要將新內(nèi)容添加到非空容器中時(shí)。然后,您復(fù)制現(xiàn)有容器并修改副本,并嘗試將更新后的副本 CAS(比較交換,即)到共享的頂級(jí)中。compareAndSet()AtomicReference

一個(gè)作家不能只是無條件地交換,因?yàn)樗赡茏罱K會(huì)得到一個(gè)非空的容器,無處放它。除非編寫器可以堅(jiān)持一批工作并旋轉(zhuǎn)等待讀取器清空隊(duì)列...


我在這里假設(shè)你的作家有一批工作可以同時(shí)排隊(duì);否則RCU對(duì)作家來說可能太貴了。很抱歉,如果我錯(cuò)過了您的問題中的一個(gè)細(xì)節(jié),可以排除這一點(diǎn)。我不經(jīng)常使用Java,所以我只是快速編寫這個(gè),以防萬一它有幫助。


查看完整回答
反對(duì) 回復(fù) 2022-08-03
  • 2 回答
  • 0 關(guān)注
  • 94 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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