首页 > 解决方案 > 通用的无锁同步

问题描述

无锁数据结构的实现有时并不容易实现。以下方法可能看起来通用且简单,但我认为这里存在一些问题:

private AtomicBoolean lock = new AtomicBoolean(false);

    public void func(...) {
        while !lock.compareAndSet(false,true);
        // Some code goes here...
        ...
        ...
        ...
        lock.set(false); 
    }
}

我认为上面的代码并不是真正的“无锁”,因为它在忙等待模式下锁定了 while 循环中的等待线程。

因此,该代码仅适用于“正确的”无锁同步是不可能的情况。

我的问题是 - 是否有可能用一些不同的方法实现一个通用的无锁,它会起作用,所以线程不会处于阻塞(如同步)或繁忙模式状态,代码将并行运行,所以我们提高了性能?

我的目标是保持线程运行。我知道如果代码很长,最好使用同步机制而不是无锁实现,所以我们假设我们在谈论短代码。

例如,下面是 Linkedlist 的示例,我认为这是一个很好的方法,但它对于常见的数据结构并不通用。如果我们在这里与上面显示的 AtomicBoolean 一起使用,它将不是真正的“无锁”。

public class LinkedList<T> {

    private AtomicReference<Link<T>> head = new AtomicReference(null);

    public  void add(T data) {
      Link<T> localHead;
      Link<T> newHead = new Link<>(null, data);

      do {
        localHead = head.get();
        newHead.next = localHead;        
      } while (!head.compareAndSet(localHead, newHead));
    }
}

标签: javamultithreadingsynchronizationlockingcompare-and-swap

解决方案


确实有无锁甚至无等待算法的通用构造方案。例如:

然而,这些通常从理论角度而不是实际角度更有趣。在实践中,专门的无锁算法通常比从这些通用结构派生的算法执行得更好。

如果您对无锁编程领域感兴趣,我建议您从《多处理器编程的艺术》一书开始。


推荐阅读