2

当我们使用诸如 ConcurrentLinkedQueue 甚至一些 BlockingQueue 之类的内置队列之一时,单个调用是原子的并且保证是线程安全的。但是当对 API 的 5 次调用中,有 4 次调用是单一的,但其中一次调用的形式为:

if(some condition)
{
    queue.call();
}

此调用需要在同步块中,因为此操作是非原子的。但是引入这个调用不也意味着从现在开始对这个队列的所有访问,无论是读还是写都应该同步?

如果是,我是否可以假设一旦代码中出现一个非原子调用,这很可能,那么所有对花哨队列的访问都必须手动同步?

4

1 回答 1

3

ConcurrentLinkedQueue不会做出与您假设的完全相同的原子保证。从javadoc:

内存一致性影响:与其他并发集合一样,线程中的操作在将对象放入 ConcurrentLinkedQueue 之前发生在另一个线程中从 ConcurrentLinkedQueue 访问或删除该元素之后的操作。

这与将 aLinkedList或某物包装在 a 中不同Collections.synchronizedList;例如,不同的线程可能会看到不同的答案size(),因为它不会锁定集合。

根据您的评论,您可能可以将 if 语句替换为对Queue's的一次调用,poll并检查检索到的元素是否为空。

于 2012-04-24T08:40:44.063 回答