Java 同步方法还是整个队列?

Java 同步方法还是整个队列?,java,synchronization,Java,Synchronization,如果一个队列要由多个线程访问,但它当前仅由一个方法修改getNextInQueue(),那么同步访问队列的最合适形式是什么 目前,我将队列声明为ConcurrentLinkedQueue,但我不希望在多个线程等待释放锁时出现死锁。另一种处理方法是不同步队列,而是同步getNextInQueue()。然而,由于这段代码将在将来使用,我认为它不会扩展。(每个修改队列的程序员都必须确保同步操作。) 想法?仅同步getNext()不是一个好主意-如果要这样做,还必须同步插入的文件示例:如果队列中没有元素

如果一个队列要由多个线程访问,但它当前仅由一个方法修改
getNextInQueue()
,那么同步访问队列的最合适形式是什么

目前,我将队列声明为
ConcurrentLinkedQueue
,但我不希望在多个线程等待释放锁时出现死锁。另一种处理方法是不同步队列,而是同步
getNextInQueue()
。然而,由于这段代码将在将来使用,我认为它不会扩展。(每个修改队列的程序员都必须确保同步操作。)


想法?

仅同步
getNext()
不是一个好主意-如果要这样做,还必须同步插入的
文件

示例:
如果队列中没有元素,线程A尝试
getNext()
并且没有完成该方法的执行-线程B可以将新项目插入队列,这将导致线程A在队列上挂起,即使队列中有新项目

总而言之:

如果一致性很重要,我会继续使用
ConcurrentLinkedQueue

我认为最简单、最正确的方法是使用
ConcurrentLinkedQueue
。然而,我不认为这会造成僵局。然而,我不确定的一点是,并发包装器如何处理使用迭代器的情况。我似乎记得必须回到旧的
synchronized
方法,即包装对底层集合的所有调用(读写)。不过,我很确定并发包装器就是这么做的。

如果它是一个
ConcurrentLinkedQueue
,并且队列状态只是线程之间共享的数据,则不需要同步任何内容。这就是使用并发集合的全部意义。生产者消费者设置不应该死锁,除非您正在做一些奇怪的事情。(就像让同一个线程成为生产者和消费者一样。)

来自文档:“迭代器是弱一致的,返回的元素反映了迭代器创建时或创建之后某个点的队列状态。”因此,如果您需要使用一致的快照,你也可以只使用
链接列表
同步
@millimoose,你错了。在迭代器对队列进行迭代时尝试更改队列将导致错误。此外,正如我所知(通过查看backport的源代码),
ConcurrentLinkedQueue
不是任何东西的包装器。它是一个独立的集合,实现时没有锁定所有数据。@millimoose您应该阅读以下内容:“此异常可能由检测到对象并发修改的方法引发,但此类修改是不允许的……请注意,fail fast行为无法保证。。。因此,编写依赖于此异常的正确性的程序是错误的:ConcurrentModificationException应该只用于检测bug。“@alfasin您能生成一个测试用例,其中,
ConcurrentLinkedQueue
可以做到这一点吗?-1:对于
java.util.concurrent
集合,情况并非如此。@millimoose我指的是他关于“另一种处理方法是不同步队列”。我想你会同意我的观点,使用一个不同步的队列并只对
getter
实现同步可能会导致死锁。嗯,我想我现在明白了,我想这句话可以解释为“使用一个不同步的集合类型”。(问题中没有任何代码很难说。)对不起。