[英]ABA in lock free algorithms
我理解ABA問題。 但我無法理解的是:他們說在有自動垃圾收集的語言中它可能無法展示。 所以我的問題是:
當啟用自動垃圾收集時,不能同時使用相同的引用分配兩個對象並共存,這是因為只要引用計數大於0,引用本身就不會被釋放和重用。
因此,當某人仍有舊參考時,您無法將參考內容“切換”為不同對象的“點”。
ABA問題與垃圾收集正交。 例如,應用程序可以將對象從鏈表移動到空閑列表,然后立即重新使用它們。 因此,在重新使用之前,對象永遠不會被釋放。 話雖如此,ABA問題可以通過這種方式發生:
Thread1:
prevHead = head;
Thread2:
prevHead = head;
newHead = getFromFreeList();
if (cas(&head, prevHead, newHead)) addToFreeList(prevHead);
Thread3:
prevHead = head;
newHead = getFromFreeList(); // Get the same object 'released' by Thread2
cas(&head, prevHead, newHead) // succeeds and put back what was removed by Thread2
Thread1:
newHead = getFromFreeList();
if (cas(&head, prevHead, newHead)) addToFreeList(prevHead);
// CAS will succeed although it shouldn't since there were
// a modification on the head done by 'Thread3' in between.
自動垃圾收集如何防止ABA問題的發生? 請參閱Herlihy Shavit的“多處理器編程的藝術”。 Quote: 它(ABA問題)經常出現,特別是在動態內存算法中 。
因此,當然ABA問題可以出現在Java中,但是由於在大多數情況下問題出現在動態內存算法中並且您不經常在java中實現此類算法,因此您不會經常在java中看到此錯誤。
是否有可能在java中,如果可以,如何? 書“多處理器編程的藝術”在java中給出了一個與無鎖並發隊列的內存回收相關的問題的例子。
有可能防止這種情況發生嗎? 引用: 通過測試避免ABA,兩個時間點的值是相同的,但是這些值之間的值已經發生了變化。 一種方法是使用AtomicStampedReference
在“多處理器編程的藝術”一書中,作者討論了程序員可能希望在Java中實現他們自己的資源池(例如,列表節點池)的情況。 然后,直接管理池的程序員繞過垃圾收集,從而提高性能。 盡管如此,必須謹慎避免ABA問題。
以下是Java中用於內存管理的Java代碼的核心:
ThreadLocal<Node> freeList = new ThreadLocal<Node>() {
protected Node initialValue() { return null; };
};
LockFreeQueueRecycle.java的完整代碼可在此處獲得:
http://booksite.elsevier.com/9780123705914/exercises/07~Chapter_10.zip
請參閱第10章的幻燈片和代碼:
http://booksite.elsevier.com/9780123705914/?ISBN=9780123705914
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.