我有一个简单的多线程问题(在Java中)。我有2组4个非常大的数组,我有4个线程,集合中的每个数组1个。我希望并行的线程检查两个集合是否有相同的值。如果其中一个数组中的某个值与另一个数组中的相应索引值不匹配,则这两个集不相同,并且所有线程都应停止它们正在执行的操作,然后转到下一组4个非常大的数组。该过程继续进行,直到比较了所有数组对并认为它们相等或不相等。我希望所有线程在其中一个线程发现不匹配时停止。实现这个的正确方法是什么?
答案 0 :(得分:1)
这是一个简单的解决方案,但我不知道它是否效率最高:只需声明一个公共boolean
字段的对象。
public class TerminationEvent {
public boolean terminated = false;
}
在启动线程之前,创建一个新的TerminationEvent
对象。在构造线程对象时使用此对象作为参数,例如
public class MyThread implements Runnable {
private TerminationEvent terminationEvent;
public MyThread(TerminationEvent event) {
terminationEvent = event;
}
}
同一个对象将传递给每个MyThread
,因此他们都会看到相同的boolean
。
现在,每个run()
中的MyThread
方法都会有类似
if (terminationEvent.terminated) {
break;
}
在循环中,并在其他线程需要停止时设置terminationEvent.terminated = true;
。
(通常我不会使用像terminated
这样的公共字段,但你说你想要效率。我认为这比getter方法更有效,但我还没有尝试过基准测试此外,在这样一个简单的例子中,当线程读取或写入terminated
字段时,我不认为你需要担心同步。)
答案 1 :(得分:0)
通常使用interrupts来停止其他线程。 Java线程不再使用Thread.stop()
,因为这被认为是不安全的,因为它解锁了线程持有的所有监视器,可能导致其他线程能够查看处于不一致状态的对象(参考:http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html )。线程没有被停止"因此,但通常用于设置标志false:
线程应该在执行计算之前检查interrupted
标志(不经常):
if (Thread.interrupted()) {
throw new InterruptedException();
}
答案 2 :(得分:0)
使用volatile变量设置中止条件。在由所有线程运行的检查循环中,让这些线程不间断地检查N个值,这样它们就不必经常获取volatile,这与值匹配测试相比可能是昂贵的。对您的解决方案进行基准测试,以找到目标硬件上N的最佳值。
另一种方法是使用ForkJoin方法,如果发现不匹配,则结果为true。将数组切片分割为类似于N的最小尺寸。