锁定无 CAS 混乱



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

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

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

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

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

您可以看到它获取值,递增它并进行比较和交换。 如果 compareAndSwap 找不到期望值,则表示另一个线程更改了该值。因此,它一次又一次地尝试,直到所有其他尝试更改值的线程都这样做了。 这是无锁的,因为没有使用锁,但不是无阻塞的,因为它可能不得不重试(这种情况很少见)不止一次(非常罕见)


1)无锁操作是使用原子操作执行的,现在这些原子操作是什么?我的意思是在某些层面上,他们还需要有锁权?那么这种无锁方法是否仅为我们提供更精细的粒度锁定?

但是,锁是使用更原始的操作实现的。否则,您将需要一个锁来实现锁定的恶心。 无锁方法使用原子操作,避免完全损坏锁。

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

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

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

术语是"并发"。它仍然需要等待另一个线程完成,它使用无锁方法来执行此操作。

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

是的。

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

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

他们不做类似同步布尔值的事情吗.....那么,既然他们正在获取锁定,即同步部分,它是如何无锁的呢?

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

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

不。

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

不。

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

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

例如,递增计数器包括

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

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

我的意思是在某些层面上,他们还需要有锁权?

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

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

CAS

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

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

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

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

相关内容

  • 没有找到相关文章

最新更新