假设我有一个int数组,一个元素num
和4个线程。
我给每个线程1/4的数组搜索{{1}}。
(搜索方法如下)
num
在我的“顶层”,我可以安排4个线程来搜索阵列的4个四分之一,但是如果一个线程中的一个找到该元素,我怎么能确保所有线程都停止搜索(假设其中没有重复)数组,因此元素最多可出现一次)。
P.S:你看,假设我的第四个线程在第一次迭代时找到了元素,我希望顶级方法立即返回,而不是等待其他3个人完成。
答案 0 :(得分:3)
您需要明确的信号。你可能会考虑内置的中断机制,或者你可以自己动手,因为它非常简单。
一个想法:在所有线程中共享AtomicBoolean
并让每个线程定期检查它。当一个线程找到答案时,它会翻转布尔值。实现定期检查的最佳选择是嵌套循环:
for (int i = start; i < end && !done.get();) {
for (int batchLimit = Math.min(i + BATCH_SIZE, end); i < batchLimit; i++) {
// your logic
}
}
这是JIT编译器最容易优化的。
只要价值没有变化,检查价值的价格就会非常低。它将在L3缓存中。价值确实发生变化的情况无关紧要,因为那时你已经完成了。
答案 1 :(得分:0)
当您找到答案并在线程之间共享时,使用标志发出信号。 AtomicBoolean
是个不错的选择。
将布尔值添加到循环结束条件中,例如
for (int i = minIdxs ; i < maxIdxs && found.get() == false; ++i){...}
当您从每个线程返回时,还要共享大小为4的CountDownLatch和countDown()。
拥有主线程await()
并且它意味着在您继续主线程之前优雅地完成所有线程。
答案 2 :(得分:0)
你可以写一个像控制器一样的课程。这个类将知道每个线程,每个线程都知道控制器。 (它像观察者模式)
如果一个线程找到答案,线程可以告诉控制器它可以通知其他线程停止。
class ControllerOfAllTheThreads{
ArrayList<TheClassesWhichDoTheSearch> list = new ArrayList<TheClassesWhichDoTheSearch>();
public void tellThemWeFoundHim(){
for (TheClassesWhichDoTheSearch theThreads : list) {
if(theThreads.isAlive() && !theThreads.isInterrupted())
theThreads.interrupt();
}
}
}