有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

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

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

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

这是。。 Choosing a data structure for a variant of producer consumer problem

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


共 (3) 个答案

  1. # 1 楼答案

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

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

  2. # 2 楼答案

    如果您希望复制队列中的项目,并确保队列中的项目尚未执行,您可以尝试以下操作:

    a)引入暂停和恢复执行的功能。见:http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html

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

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

  3. # 3 楼答案

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

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

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

    ConcurrentLinkedQueue。迭代器()被记录为

    Returns an iterator over the elements in this queue in proper sequence. The returned iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.