java如何以线程安全的方式访问ThreadpoolExecutor的底层队列
getQueue()方法提供对ThreadPoolExecutor中底层阻塞队列的访问,但这似乎不安全
遍历此函数返回的队列可能会错过ThreadPoolExecutor对队列所做的更新
“方法getQueue()允许访问工作队列以进行监视和调试。强烈建议将此方法用于任何其他目的。”
如果要遍历ThreadPoolExecutor使用的工作队列,您会怎么做?或者有其他的方法吗
这是。。 Choosing a data structure for a variant of producer consumer problem
现在,我正在尝试多生产者多消费者,但我想使用一些现有的线程池,因为我不想自己管理线程池,而且我还想在ThreadPoolExecutor完成某些任务时进行回调,并能够以线程安全的方式检查“inprogress transactions”数据结构
# 1 楼答案
如果你在你的accepted answer中遵循了Jon Skeet的建议,那么你将通过锁控制对队列的访问。如果在进行中的队列上获得锁,则可以保证遍历不会错过其中的任何项
当然,这样做的问题是,当您执行遍历时,队列上的所有其他操作(试图访问它的其他生产者和消费者)都会被阻塞,这可能会对性能产生非常可怕的影响
# 2 楼答案
如果您希望复制队列中的项目,并确保队列中的项目尚未执行,您可以尝试以下操作:
a)引入暂停和恢复执行的功能。见:http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html
b)首先暂停队列,然后复制队列,然后恢复队列
然后我有我自己的问题。我看到的问题是,当您执行“Runnable”时,“Runnable”并不是放在队列中,而是放在FutureTask的“包装器”中,我找不到任何方法来确定我正在查看哪一个Runnable。因此,抓取和检查队列是非常无用的。有人知道我错过了吗
# 3 楼答案
您可以重写beforeExecute和afterExecute方法,让您知道任务已经开始和完成。可以重写execute(),以了解何时添加任务
问题是,队列不是为查询而设计的,任务可以在看到它之前就被消耗掉。解决这个问题的一种方法是创建自己的队列实现(可能覆盖/包装ConcurrentLinkedQueue)
顺便说一句:队列是线程安全的,但是不能保证你会看到每个条目
ConcurrentLinkedQueue。迭代器()被记录为