LinkedBlockingQueue 的插入和删除方法线程安全吗?

发布于 2024-08-30 03:24:08 字数 229 浏览 2 评论 0原文

我在两个不同的线程之间使用 LinkedBlockingQueue 。一个线程通过 add 添加数据,而另一个线程通过 take 接收数据。

我的问题是,我是否需要同步对 addtake 的访问。 LinkedBlockingQueue 的插入和删除方法线程安全吗?

I'm using LinkedBlockingQueue between two different threads. One thread adds data via add, while the other thread receives data via take.

My question is, do I need to synchronize access to add and take. Is LinkedBlockingQueue's insert and remove methods thread safe?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

枯叶蝶 2024-09-06 03:24:08

是的。来自文档

“BlockingQueue 实现是
线程安全。所有排队方式
使用原子方式实现其效果
内部锁或其他形式的
并发控制。然而,大部分
集合操作addAll,
containsAll、retainAll 和 removeAll
不一定执行
除非另有说明,否则以原子方式
在一个实现中。原来如此
可能,例如,对于 addAll(c)
之后失败(抛出异常)
仅添加其中的一些元素
c.”

编辑: addAll 行为不是多线程特定的问题,因为单线程场景可能有完全相同的问题。

在单线程应用程序中,创建一个 ArrayList list 最后有 9 个非空元素和 1 个空元素

调用 queue.addAll(list);

假设它按顺序添加元素(我不相信这是保证的) ),它会添加前 9 个,然后抛出异常(BlockingQueue 不允许 null 元素。) 9 仍然会被添加到队列中。

  1. 但很可能会 原子要求很多,集合是否是线程安全的,它需要对整个集合进行快照然后回滚是的,它可以针对许多集合实现(尽管对于某些集合来说会很复杂),但我不会。假设任何集合(无论是否是线程安全的)都这样做。

底线:集合很复杂,并且它们的保证各不相同,查阅文档很重要。
线程安全只是许多人关心的问题之一。

Yes. From the docs:

"BlockingQueue implementations are
thread-safe. All queuing methods
achieve their effects atomically using
internal locks or other forms of
concurrency control. However, the bulk
Collection operations addAll,
containsAll, retainAll and removeAll
are not necessarily performed
atomically unless specified otherwise
in an implementation. So it is
possible, for example, for addAll(c)
to fail (throwing an exception) after
adding only some of the elements in
c."

EDIT: The addAll behavior is not a multithreading-specific issue, because a single-threaded scenario can have exactly the same problem.

In a single-threaded app, create an ArrayList list with 9 non-null elements and one null element at the end.

Call queue.addAll(list);

Assuming it adds the elements in sequential order (I don't believe this is guaranteed but it likely will), it will add the first 9, then throw an exception. (BlockingQueue does not allow null elements.) The 9 will still get added to the queue.

  1. Asking for addAll to be atomic is asking a lot, whether the collection is thread-safe or not. It requires snapshoting the whole collection then rolling back. Yes, it could be implemented for many collections (though for some it would be complex), but I wouldn't assume any collection (thread-safe or not) did.

Bottom line: Collections are complex and their guarantees vary. It's important to consult the documentation.
Thread-safety is just one concern of many.

坐在坟头思考人生 2024-09-06 03:24:08

是的,BlockingQueue 方法 add()take() 是线程安全的但有区别

add ()take() 方法使用 2 个不同的 ReentrantLock 对象。

add() 方法使用

private final ReentrantLock putLock = new ReentrantLock();

take() 方法使用

private final ReentrantLock takeLock = new ReentrantLock();

因此,对 add() 方法的同时访问是同步的。同样,同时访问 take() 方法也是synchronized

但是,同时访问 add()take() 方法不是同步,因为它们使用 2 个不同的锁对象(除了在队列满/空的边缘条件期间)。

Yes, BlockingQueue methods add() and take() are thread safe but with a difference.

add () and take() method uses 2 different ReentrantLock objects.

add() method uses

private final ReentrantLock putLock = new ReentrantLock();

take() method uses

private final ReentrantLock takeLock = new ReentrantLock();

Hence, simultaneous access to add() method is synchronized. Similarly, simultaneous access to take() method is synchronized.

But, simultaneous access to add() and take() method is not synchronized since they are using 2 different lock objects (except during edge condition of queue full / empty).

撧情箌佬 2024-09-06 03:24:08

简单地说,是的,它绝对是线程安全的,否则它就没有资格作为 ThreadPoolExecutor 存储元素的候选者。

只需添加和检索元素,无需担心 BlockingQueue 的并发性。

Simply Yes, its definitely thread safe otherwise it wouldn't have qualified as a candidate for storing element for ThreadPoolExecutor.

Simply add and retrieve element without worrying about concurrency for BlockingQueue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文