Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何以线程安全的方式访问ThreadpoolExecutor的底层队列_Java_Executors - Fatal编程技术网

Java 如何以线程安全的方式访问ThreadpoolExecutor的底层队列

Java 如何以线程安全的方式访问ThreadpoolExecutor的底层队列,java,executors,Java,Executors,getQueue()方法提供对ThreadPoolExecutor中底层阻塞队列的访问,但这似乎不安全 遍历此函数返回的队列可能会错过ThreadPoolExecutor对队列所做的更新 “方法getQueue()允许访问工作队列以进行监视和调试。强烈建议将此方法用于任何其他目的。” 如果要遍历ThreadPoolExecutor使用的工作队列,您会怎么做?或者有其他的方法吗 这是。。 现在,我正在尝试多生产者多消费者,但我想使用一些现有的线程池,因为我不想自己管理线程池,而且我还想在Thre

getQueue()方法提供对ThreadPoolExecutor中底层阻塞队列的访问,但这似乎不安全

遍历此函数返回的队列可能会错过ThreadPoolExecutor对队列所做的更新

“方法getQueue()允许访问工作队列以进行监视和调试。强烈建议将此方法用于任何其他目的。”

如果要遍历ThreadPoolExecutor使用的工作队列,您会怎么做?或者有其他的方法吗

这是。。


现在,我正在尝试多生产者多消费者,但我想使用一些现有的线程池,因为我不想自己管理线程池,而且我还想在ThreadPoolExecutor完成某些任务时进行回调,并能够以线程安全的方式检查“inprogress事务”数据结构。

您可以覆盖beforeExecute和afterExecute方法,让您知道任务已经开始和完成。您可以重写execute(),以了解何时添加任务

您遇到的问题是,队列不是为查询而设计的,任务可以在您看到它之前就被使用。解决此问题的一种方法是创建自己的队列实现(可能覆盖/包装ConcurrentLinkedQueue)

顺便说一句:队列是线程安全的,但是不能保证您会看到每个条目

ConcurrentLinkedQueue.iterator()记录为

按正确的顺序返回此队列中元素的迭代器。返回的迭代器是一个“弱一致”迭代器,它永远不会抛出ConcurrentModificationException,并保证在构造迭代器时遍历元素,并且可能(但不保证)反映构造之后的任何修改


如果您在前面的问题中遵循Jon Skeet的建议,那么您将通过锁控制对队列的访问。如果在进行中队列上获得锁,则可以保证遍历不会错过其中的任何项


当然,这样做的问题是,当您执行遍历时,队列上的所有其他操作(其他生产者和消费者尝试访问它)都将被阻止,这可能会对性能产生非常可怕的影响。

如果您希望复制队列中的项并确保队列中的项未被执行,你可以试试这个:

a) 介绍暂停和恢复执行的功能。见:

b) 首先暂停队列,然后复制队列,然后恢复队列


然后我有我自己的问题。我看到的问题是,当您执行“Runnable”时,“Runnable”并没有放在队列中,而是放在FutureTask的“包装器”中,我无法找到任何方法来确定我正在查看哪一个Runnable。因此,抓取和检查队列是非常无用的。有人知道我错过了吗?

我可以在那个时间点拍摄快照,比如Collections.unmodifiable(),但我需要知道在拍摄快照时,队列不会改变。因此,我需要将队列锁定在某个位置,但ThreadPoolExecutor将不遵守我的锁定约束。您是否建议我创建自己的CustomBlockingqueue,并将其传递给ThreadPoolExecutor?我不明白这会有什么帮助,请详细说明。Collections.unmodifiable()可以被视为原子操作吗?因为,我认为只有原子操作是线程安全的。问题是ConcurrentLinkedQueue是为并发/无锁队列设计的。ThreadPoolExecutor在这件事上没有发言权。您可以给它一个按您所需的方式运行的队列。您不能对队列使用
Collections.unmodifiableXxxx()
。它只包装基础集合,不复制它。原子操作更容易使线程安全,但是可以通过首先锁定集合使迭代器线程安全。(假设集合荣誉锁)请您也扩展一下“队列是线程安全的,但是不能保证您会看到每个条目”这句话。我认为线程安全意味着每个条目都会被看到。感谢您的回复。是的,我正试图听从他的建议,额外使用threadExecutor来为我处理线程池管理。我想我可以在没有ThreadPoolExecutor的情况下自己完成这项工作,但接下来我必须编写额外的代码来处理threadpool,并在任务完成时回调,这是我试图避免的。谢谢Paul,你回答的最后一段完全有意义,因为我意识到我需要在单独的数据结构中维护我的可运行程序。