无等待和无锁算法的示例/说明

Posted

技术标签:

【中文标题】无等待和无锁算法的示例/说明【英文标题】:Examples/Illustration of Wait-free And Lock-free Algorithms 【发布时间】:2011-05-11 19:17:06 【问题描述】:

我读过无等待会导致所有线程独立完成,而无锁可确保整个程序完成。我不太明白。谁能举个例子(java)来说明这一点。

编辑:无锁是否意味着程序没有死锁?

【问题讨论】:

【参考方案1】:

如果一个程序是无锁的,这基本上意味着它的至少一个线程可以保证在任意时间段内取得进展。如果一个程序死锁,它的所有线程(以及整个程序)都无法取得进展——我们可以说它不是无锁的。由于无锁程序可以保证取得进展,因此它们可以保证完成(假设有限执行且无异常)。

Wait-free 是一种更强的条件,这意味着 每个 线程都可以保证在任意时间段内取得进展,而不管线程执行的时间/顺序如何;所以我们可以说线程独立完成。所有免等待程序都是免锁的。

我不知道任何 Java 示例可以说明这一点,但我可以告诉您,无锁/无等待程序通常是在没有锁的情况下实现的,使用 CAS 指令等低级原语。

【讨论】:

这是否意味着任何没有死锁的程序都是无锁的?如果其中一个线程完成了,怎么能说整个程序已经完成了呢? @iJeeves:无锁意味着没有锁,所以死锁是不可能的。不,你不能。 您想知道程序的无锁属性如何暗示它可以保证完成?好吧,如果有有限数量的线程具有有限的工作负载,并且至少有一个活动线程保证在一段时间内在其工作负载上取得进展(无锁属性),那么我们知道所有线程(以及因此程序) 最终会完成。 我们应该清楚术语;无锁并不意味着无死锁,它是使用无锁算法的副作用......我认为这个术语更多的是关于不使用互斥锁来实现共享资源之间的同步(这是内森在谈论时提到的CAS 指令)。 您将“无锁”与“无死锁”混淆了。【参考方案2】:

非阻塞算法是lock-free,如果有保证的系统范围的进度,wait-free,如果也有保证的每线程进度。因此,wait-free 算法也是lock-free;但是,反之亦然。但是,两者都是non-blocking algorithms。

此wiki entry 非常适合理解lock-freewait-free 机制。

嗯,java.util.concurrent.atomic 包是 lock-free 对单个变量进行编程的示例。而在 Java 7 中,ConcurrentLinkedQueuewait-free 实现的一个示例。

为了进一步了解,我希望您阅读这篇文章,Going atomic,作者是 Brian Goetz——Java Concurrency in Practice 的作者。

【讨论】:

奇怪的是,虽然 ConcurrentLinkedQueue 在 Java 7 中确实被描述为“无等待”实现,但在 Java 8 中,该描述更改为不太严格的“非阻塞”(该描述仍然是Java 13,本评论的当前版本):docs.oracle.com/javase/8/docs/api/java/util/concurrent/…我想知道发生了什么变化? @Peter,我认为,他们将单词改为“非阻塞”,以匹配 Maged M. Michael 和 Michael L. Scott 的原始论文的标题,作为链接在那里——链接似乎被破坏了,在 Java 7/8 文档中。 @AdeelAnsari 无锁并不意味着“没有锁”。这通常称为无锁。 在我看来他们改进了文档,因为实际论文没有描述无等待算法,我认为实现实际上只是无锁或非阻塞,而不是事实上无需等待。【参考方案3】:

从弱到强的条件:

一个方法是无锁,如果它保证经常某个方法调用在有限的步骤中完成。

如果方法保证每个调用在有限的步骤中完成其执行,则该方法是免等待

显然,任何无等待的方法实现也是无锁的,但反之则不然。无锁算法承认某些线程可能会饿死。

但是,从“实际角度”来看,在很多情况下,饥饿虽然可能,但极不可能发生,因此 快速无锁算法可能比慢速无等待算法更具吸引力。强>

注意:更强大的属性称为“bounded wait-free”,意思是:步数有限制 可以进行方法调用。

【讨论】:

以上是关于无等待和无锁算法的示例/说明的主要内容,如果未能解决你的问题,请参考以下文章

什么是非无锁的无阻塞算法示例?

folly无锁队列正确性说明

JAVA语言中 有返回值的方法和无返回值的方法有啥区别啊 请举例子说明!!

单插入多读取列表是否安全无锁?

动态无锁内存分配器

双重检查创建线程安全的单例和无锁