[英]Multiprocessor programming: lock-free stacks
在為即將到來的並發系統考試做准備的過程中,我試圖從教科書“多處理器編程的藝術”中完成一些問題。 一個問題是困擾我:
練習129:在我們的LockFreeStack對象中使用相同的共享BackOff對象進行推送和彈出是否有意義? 我們怎樣才能在EliminationBackOffStack中構建空間和時間的退避?
這個問題讓我感到困惑,因為我想到的第一件事就是它沒有意義,因為所有退避對象都會讓進程等待,所以為什么不分享呢? 問題的第二部分完全沒有我,任何幫助都是最受歡迎的。
LockFreeStack的代碼:
public class LockFreeStack<T> {
AtomicReference<Node> top = new AtomicReference<Node>(null);
static final int MIN_DELAY = ...;
static final int MAX_DELAY = ...;
Backoff backoff = new Backoff(MIN_DELAY, MAX_DELAY);
protected boolean tryPush(Node node) {
Node oldTop = top.get();
node.next = oldTop;
return(top.compareAndSet(oldTop, node));
}
public void push(T value) {
Node node = new Node(value);
while (true) {
if (tryPush(node)) {
return;
} else {
backoff.backoff();
}
}
}
不確定我的任何ramblings是否有幫助,但無論如何我都會按“發布”按鈕。
答案取決於backoff()
的實現。 由於此處的目標是避免同步,因此不會有任何本地存儲 - 可能是ThreadLocal
某些存儲。 如果退避算法使用隨機數發生器,它也需要是可重入的。 所以很有可能你能夠在pop
和push
之間分享它 - 現在你想要。 由於推送和彈出都試圖改變top
引用,如果后退給予連續線程大不相同的數字將是好的。 推或彈出更多的爭論? 我們是否需要采用一種或另一種方法更積極地退縮? 如果這是一個通用堆棧,那么你就不會知道。
關於退避如何“重組”,我也不確定。 您是否可以使用成功的推送或彈出機會來減少退避時間? 如何在ThreadLocal
指定的序列中隨機退避等待與素數之間的差異如何?
從同步的角度來看第一個問題,我認為為推送和彈出提供相同的BackOff
對象是有意義的。 無論這個類的實現如何。 這樣做的原因是,如果我們有一個堆棧,我們必須在刪除和添加項目到堆棧時保持一致的狀態。 但是,如果我們只是偷看(查看堆棧的第一個元素或頂部),那么我們可能會有多個BackOff
對象查看它,因為讀取不應該鎖定有問題的數據源。 第二個問題是要求為該類發布代碼。
在這種情況下使用退避是過度殺戮。
任何真實世界的應用程序都應該花費更多的時間來處理節點,而不是在堆棧上下移動。 通過比較的堆棧操作應該非常短。 因此,兩個線程不太可能同時訪問堆棧。 但是,它有時會發生,因此您需要編寫正確的代碼。
public void push(T value) {
Node node = new Node(value);
while (!tryPush(node))
backoff.backoff();
}
恕我直言:可以縮短為
public void push(T value) {
Node node = new Node(value);
while (!tryPush(node));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.