实现在执行过程中返回结果的多个并发线程的最佳方法?
Posted
技术标签:
【中文标题】实现在执行过程中返回结果的多个并发线程的最佳方法?【英文标题】:Best way to implement multiple concurrent threads that return results in the middle of execution? 【发布时间】:2015-03-25 06:41:54 【问题描述】:我正在负载测试工具中实现以下功能,以模拟目标应用程序的重负载:
同时启动多个线程来执行相同类型的操作。
每个线程将循环 n 次。在每个循环结束时,测试结果都可用并添加到一个列表中,该列表在所有循环完成运行后返回。
我目前正在使用Callable
和Future
,并在所有线程完成运行后将所有线程返回的结果列表放入另一个列表并给我Future
。问题是如果程序的执行被中断,我可能会丢失可用的东西。我希望能够在线程仍在处理剩余循环时保存完成循环中可用的结果。
Java 并发库中是否有适合此目的的东西?或者我正在构建的负载测试功能是否有更好的设计?
提前致谢!
【问题讨论】:
我建议在生成结果时将结果添加到并发队列(例如 ConcurrentLinkedQueue),并从队列中读取主线程。 谢谢。这与 BlockingQueue 有何不同? 【参考方案1】:您可以在结果发生时将结果传递给 BlockingQueue。这可以被另一个线程或首先触发任务的线程拾取。
【讨论】:
我认为这样做可能比重新设计整个事情更容易。但是,以防万一我选择重写结构以使用池,我需要使用哪些接口和类来监视池? (即看一个是否完成并在池中返回一个结果,这样我就可以收集结果并在池中放入一个新的) @Max 收集结果的线程可以将所有任务放入队列中,然后在未来列表中等待结果。如果您只有大约 10,000 个任务,您可能不需要在处理它们时生成它们,而是在开始时生成它们。【参考方案2】:java.util.concurrent.CyclicBarrier 类是一种同步机制,可以通过某种算法同步线程。换句话说,它是所有线程必须等待的屏障,直到所有线程都到达它,然后任何线程才能继续。
创建循环障碍
当您创建 CyclicBarrier 时,您可以指定在释放它们之前要等待的线程数。以下是创建 CyclicBarrier 的方法:
CyclicBarrier barrier = new CyclicBarrier(2);
在 CyclicBarrier 处等待
这是线程在 CyclicBarrier 处等待的方式:
barrier.await();
您还可以为等待线程指定超时。当超时过去时,线程也被释放,即使不是所有 N 个线程都在 CyclicBarrier 处等待。以下是指定超时的方法:
barrier.await(10, TimeUnit.SECONDS);
等待线程在 CyclicBarrier 处等待,直到:
最后一个线程到达(调用 await() ) 线程被另一个线程中断(另一个线程调用它的interrupt()方法) 另一个等待线程被中断 另一个等待线程在 CyclicBarrier 处等待时超时 CyclicBarrier.reset() 方法被某个外部线程调用。
【讨论】:
以上是关于实现在执行过程中返回结果的多个并发线程的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章
2020最新Java工程师面试题-Java 并发编程(附答案,持更中)