blockingqueue与没有take()的lock-free concurrentqueue相比的优势

The strength of blockingqueue compared to lock-free concurrentqueue without take()

我是多线程编程的初学者

一直在多线程环境下使用Concurrent类,突然对使用blockingqueue很好奇

我认为 Concurrent 类 像 ConcurrentHashMap 使用锁定。

最近正好用到QUEUE,看了一下线程安全的队列。于是知道有BlockingQueue和linkedConcurrentQueue,就研究了这两个队列。

阻塞队列使用锁定是线程安全的。这就是我想的典型的线程安全方式。

Concurrentqueue 通过使用称为 CAS 的算法进行线程安全处理。 但是,我不知道这个CAS的目标是队列本身还是属于队列的元素。 即使多个线程同时轮询concurrentqueue中的元素,它们轮询的是不同的元素吗?不是有一次轮询同一个元素的情况吗?

如果是这样,与阻塞队列相比,无锁并发队列看起来太好了……阻塞队列仍然被弃用和存在的原因是什么? (take() 方法除外)

有没有我想研究或参考的文章?谢谢!

阻塞操作不能是无锁的(反之亦然)。无锁操作提供 进度保证 。这是来自 Wikipedia 的定义:

An algorithm is lock-free if, when the program threads are run for a sufficiently long time, at least one of the threads makes progress (for some sensible definition of progress).

被阻塞的线程在“解除阻塞”之前无法取得进展。但这通常意味着某些其他线程必须取得进展才能解除阻塞的线程。因此,被阻塞的线程 取决于 其他线程的进度。在无锁操作中,情况并非如此 - 如果其他线程正在取得进展并因此干扰第一个线程,则只能阻止线程取得进展。

这就是为什么无锁队列不能有阻塞弹出操作的原因,该操作会在队列为空的情况下阻塞,等待其他线程推送项目。相反,他们通常有一个 tryPop 操作来指示它是否成功。

(无锁)比较和交换(CAS)操作通常只能在单个指针上执行。它是无锁算法所需的基本操作之一。对于 ConcurrentLinkedQueue(Michael 和 Scott 在 Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms 中提出的队列的实现),使用 CAS 操作更新头指针和尾指针。

并发编程的主题非常广泛和复杂。如果您真的有兴趣,我建议您从这本好书入手 The Art of Multiprocessor Programming