嘿伙计们,
我正在阅读这些所谓的非阻塞技术,但我几乎没有疑问:
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)无锁操作是使用原子操作执行的,现在这些原子操作是什么?
例如,递增计数器包括
- 读取当前值,
- 递增内存中的值,
- 写回更新的值。
原子性意味着这些都作为一个单一的、可重复的变化发生。
我的意思是在某些层面上,他们还需要有锁权?
错。CAS 背后的基本思想是执行上述前两个步骤,然后在第三个步骤之前,他们检查值是否在两者之间更改,如果是,则失败。然后,稍后可以使用新值重试更改。
不涉及经典锁定,因为 3 个步骤中的每一个本身都是原子的。现代处理器支持第 3 个(比较和交换)操作,因此您可能会说它涉及寄存器级别的某种锁定(坦率地说,我不知道它是如何实现的),但无论如何,这与通常所说的 Java 锁定不同。
CAS的好处是提高了性能,因为即使当前 JVM 中的锁定性能有所提高,CAS 仍然更便宜,尤其是在发生争用的情况下(即当多个线程在操作上发生冲突时)。在这种情况下,使用锁,一个或多个线程被挂起,并将新线程引入上下文中,即使不涉及交换内存,这也是一个非常昂贵的操作。
2)他们说非阻止列表,现在非阻止列表应该是什么
在这里,您可能会混淆两个不同的术语。非阻塞列表是指在插入/删除时不阻塞的列表,这通常意味着其大小不受限制(例如 CopyOnWriteArrayList
)。与此形成对比,例如阻塞队列(例如 ArrayBlockingQueue
),它具有固定的最大大小,并且在达到其大小限制时,将阻止其他插入调用,直到有更多可用空间(在其他线程从队列中删除元素之后)。
使用无锁算法(如 ConcurrentHashMap
)实现线程安全的集合与非阻塞集合不同。