LinkedBlockingQueue 的插入和删除方法线程安全吗?
我在两个不同的线程之间使用 LinkedBlockingQueue
。一个线程通过 add
添加数据,而另一个线程通过 take
接收数据。
我的问题是,我是否需要同步对 add
和 take
的访问。 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的。来自文档:
编辑:
addAll
行为不是多线程特定的问题,因为单线程场景可能有完全相同的问题。在单线程应用程序中,创建一个 ArrayList
list
最后有 9 个非空元素和 1 个空元素调用
queue.addAll(list);
假设它按顺序添加元素(我不相信这是保证的) ),它会添加前 9 个,然后抛出异常(BlockingQueue 不允许 null 元素。) 9 仍然会被添加到队列中。
底线:集合很复杂,并且它们的保证各不相同,查阅文档很重要。
线程安全只是许多人关心的问题之一。
Yes. From the docs:
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.
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.
是的,
BlockingQueue
方法add()
和take()
是线程安全的但有区别。add ()
和take()
方法使用 2 个不同的ReentrantLock
对象。add(
) 方法使用take()
方法使用因此,对
add()
方法的同时访问是同步的。同样,同时访问take()
方法也是synchronized
。但是,同时访问
add()
和take()
方法不是同步
,因为它们使用 2 个不同的锁对象(除了在队列满/空的边缘条件期间)。Yes,
BlockingQueue
methodsadd()
andtake()
are thread safe but with a difference.add ()
andtake()
method uses 2 differentReentrantLock
objects.add(
) method usestake()
method usesHence, simultaneous access to
add()
method is synchronized. Similarly, simultaneous access totake()
method issynchronized
.But, simultaneous access to
add()
andtake()
method is notsynchronized
since they are using 2 different lock objects (except during edge condition of queue full / empty).简单地说,是的,它绝对是线程安全的,否则它就没有资格作为 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.