0

嘿伙计们,
我正在阅读这些所谓的非阻塞技术,但我几乎没有疑问:

1)使用原子操作执行无锁操作,现在这些原子操作是什么?我的意思是在一定程度上他们也需要锁,对吗?那么这种无锁方法是否只为我们提供了更细粒度的锁定?
2)他们说非阻塞列表,现在非阻塞列表应该是什么:如果多个线程同时插入,只有一个会成功,另一个会做其他工作对吗?,但是如果其他线程别无选择,只能插入一个节点,那么它为什么是非阻塞的?在前一个完成之前它不会被阻止吗?
3)在java中,它们如何进行原子操作?他们不做类似的事情吗 synchronized boolean ..... 那么它是如何无锁的,因为他们正在获取锁,即同步部分?4)CAS通常用于实现原子操作。那么 cas 是否只允许对同一对象进行一项操作,并停止(阻止)其他想要对同一对象进行操作的操作?很抱歉有这么多疑问...请澄清...

编辑 当我有一个结构要更新时会发生什么?硬件也支持吗?不对,那么语言不会在某种程度上获取锁以使这些结构操作原子化吗?
关于JAVA:有 AtomicReference 和 AtomicReferenceFieldUpdater 类提供对对象(结构或任何类型的对象)的更新,所以我们可以在性能方面比较它们,我的意思是速度吗?两者都使用 Unsafe 类,它使用 Native 类。

4

2 回答 2

8

这是 AtomicInteger 中一个简单的无锁方法

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

您可以看到它获取值、递增它并执行 compareAndSwap。如果 compareAndSwap 没有找到期望值,则意味着另一个线程已更改该值。所以它会一次又一次地尝试,直到所有其他尝试更改值的线程都这样做了。这是无锁的,因为没有使用锁,但不是阻塞的,因为它可能需要多次重试(很少见)(非常罕见)


1)使用原子操作执行无锁操作,现在这些原子操作是什么?我的意思是在一定程度上他们也需要锁,对吗?那么这种无锁方法是否只为我们提供了更细粒度的锁定?

然而,锁是使用更原始的操作来实现的。否则你将需要一个锁来实现一个锁adnauseum。无锁方法使用避免完全锁定的原子操作。

2)他们说非阻塞列表,现在非阻塞列表应该是什么:如果多个线程同时插入,只有一个会成功,另一个会做其他工作对吗?

如果它的线程安全,它们应该都成功,一次一个。

但是如果其他线程除了插入节点别无选择,那它怎么会是非阻塞的呢?

术语是“并发”。它仍然必须等待其他线程完成,它使用无锁方法来完成此操作。

在前一个完成之前它不会被阻止吗?

是的。

3)在java中,它们如何进行原子操作?

有一个调用本机方法来执行原子操作。你可以通过阅读代码看到这一点。;) 从生成的本机代码来看,这些本机方法被转换为机器代码指令以提高性能(而不是真正的方法调用)

他们不做类似同步布尔之类的事情.....那么它是如何无锁的,因为他们正在获取锁,即同步部分?

不,如果您阅读代码,您会发现它没有。

4)CAS通常用于实现原子操作。所以 cas 不允许在同一个对象上只发生一个操作,

不。

并停止(阻止)其他想要对同一对象进行操作的人?

不。

同样,如果你看看它是如何使用的,它可能更有意义。

于 2011-05-13T12:39:50.757 回答
2

1)使用原子操作执行无锁操作,现在这些原子操作是什么?

例如增加一个计数器包括

  1. 读取当前值,
  2. 增加内存中的值,
  3. 写回更新的值。

原子性意味着这些都作为一个单一的、不可中断的变化发生。

我的意思是在一定程度上他们也需要锁,对吗?

错误的。CAS 背后的基本思想是执行上面的前两步,然后在第三步之前,检查值是否在两者之间发生了变化,如果是,则失败。然后可以稍后使用新值重试更改。

不涉及经典锁定,因为这 3 个步骤中的每一个本身都是原子的。现代处理器支持第三个(比较和交换)操作,因此您可能会说它涉及寄存器级别的某种锁定(坦率地说,我不知道它是如何实现的),但无论如何,这与 Java 中通常所说的锁定不同。

CAS 的好处是提高了性能,因为即使在当前 JVM 中提高了锁定性能,CAS 仍然更便宜,尤其是在争用的情况下(即当多个线程在一个操作上发生冲突时)。在这种情况下,使用锁,一个或多个线程被挂起,而是将一个新线程带入上下文,即使它不涉及交换内存,这也是一项非常昂贵的操作。

2)他们说非阻塞列表,现在非阻塞列表应该是什么

在这里,您可能会混淆两个不同的术语。非阻塞列表是在插入/删除时不阻塞的列表,这通常意味着它的大小是不受限制的(例如CopyOnWriteArrayList)。将此与例如具有固定最大大小的阻塞队列(例如,ArrayBlockingQueue

使用无锁算法(例如ConcurrentHashMap)实现线程安全的集合与非阻塞集合不同。

于 2011-05-13T12:17:28.560 回答