Java 将ConcurrentLinkedQueue与一些非原子操作一起使用

Java 将ConcurrentLinkedQueue与一些非原子操作一起使用,java,multithreading,queue,Java,Multithreading,Queue,当我们使用一个内置队列,比如ConcurrentLinkedQueue,甚至一些BlockingQueue时,单个调用是原子的,并且保证线程安全。 但在5个API调用中,有4个调用是单调用,但有一个调用的形式如下: if(some condition) { queue.call(); } 此调用需要在同步块中,因为此操作是非原子的。 但是引入这个调用是否意味着从现在起,对这个队列的所有访问,无论是读还是写,都应该同步 如果是,我是否可以假设,一旦一个非原子调用在代码中爬行(这很有可能)

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

if(some condition)
{
    queue.call();
}
此调用需要在同步块中,因为此操作是非原子的。 但是引入这个调用是否意味着从现在起,对这个队列的所有访问,无论是读还是写,都应该同步


如果是,我是否可以假设,一旦一个非原子调用在代码中爬行(这很有可能),那么对奇特队列的所有访问都必须手动同步?

ConcurrentLinkedQueue
没有提供与您假设的完全相同的原子保证。从javadoc:

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

这与将
链接列表
或其他东西包装到
集合中不同;例如,对于
size()
,不同的线程可能会看到不同的答案,因为它不会锁定集合


根据您的评论,您可能可以使用对
Queue
poll
的单个调用来替换if语句,并检查检索到的元素是否为null。

条件是什么?它与队列相关吗?是的,类似于queue.isEmpty()。如果使用正确,您应该永远不需要同步队列。IMHO,如果您使用ExecutorService,很少需要直接使用队列。