首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无锁CAS混淆

无锁CAS混淆
EN

Stack Overflow用户
提问于 2011-05-13 12:12:04
回答 2查看 1.9K关注 0票数 0

嘿伙计们,

我正在读这些所谓的非阻塞技巧,但我没有什么疑问:

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

2)他们说非阻塞列表,现在非阻塞列表应该是什么:如果一个以上的线程在同一个插入时出现,那么只有一个线程会成功,另一个线程会做一些其他的工作,对吗?但是如果其他线程除了插入一个节点之外别无选择,那么为什么它是非阻塞的?它会不会被阻塞,直到上一次完成??

3)在java中,它们是如何进行原子操作的?他们不是在做类似于synchronized boolean .....的事情吗?那么,既然他们获得了锁(即同步部分),那么它是如何无锁的呢? 4) CAS通常用于实现原子操作。那么cas不允许在同一个对象上只执行一次操作,而停止()--其他想对同一个对象操作的操作吗?抱歉有这么多疑问..。请澄清..。

编辑当我有要更新的结构时会发生什么?硬件也支持它吗?没有权利,所以语言不是在一定程度上获取锁来使这些结构操作成为原子的吗?

关于:有AtomicReference和AtomicReferenceFieldUpdater类提供对象的更新(结构或任何类型的对象),所以我们能比较它们的性能(我指的是速度)吗?在tern中都使用不安全类,后者使用本机类。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-13 12:39:50

下面是AtomicInteger中一种简单的无锁方法

代码语言:javascript
复制
public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

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

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

但是,锁是使用更原始的操作实现的。否则,您将需要一个锁来实现一个锁,adnauseum。无锁方法使用原子操作,避免了完全失效的锁。

(

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

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

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

这个词是“并发”。它仍然要等待另一个线程完成,它使用一种无锁的方法来完成这个任务。

会不会被阻塞,直到上一次完成??

是。

3)在java中,它们是如何原子操作的?

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

他们不做类似于同步布尔的事情.那么,既然它们获得了锁,即同步部分,那么它是如何无锁的呢?

不,如果你读了代码,你就会发现它没有。

4)通常用于实现原子操作。所以cas不允许对同一个对象只进行一次操作,

不是的。

和停止(阻止)其他想要在同一个对象上操作的人?

不是的。

再一次,如果你看看它是如何使用的,它可能更有意义。

票数 8
EN

Stack Overflow用户

发布于 2011-05-13 12:17:28

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

例如,递增计数器包括

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

原子性意味着所有这些都是作为一个单一的、不可破坏的变化发生的。

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

不对。CAS背后的基本思想是执行上面的前两个步骤,然后在第三个步骤之前,检查值在两者之间是否被更改,如果是,则失败。然后,可以使用新的值重新尝试更改。

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

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

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

在这里,您可能混淆了两个不同的术语。非阻塞列表是指在插入/删除时不阻塞的列表,这通常意味着它的大小没有限制(例如CopyOnWriteArrayList)。这与具有固定最大大小的阻塞队列(例如ArrayBlockingQueue)形成对比,并且在达到其大小限制时,额外的插入调用被阻塞,直到有更多的空间可用(在其他线程从队列中删除元素之后)。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5991620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档