【问题标题】:Multi-threaded array comparison - Pushing events to a thread?多线程数组比较 - 将事件推送到线程?
【发布时间】:2023-04-04 23:38:02
【问题描述】:

我有一个简单的多线程问题(在 Java 中)。我有 2 组 4 个非常大的数组,我有 4 个线程,组中的每个数组都有 1 个线程。我希望线程并行检查两组是否具有相同的值。如果其中一个数组中的一个值与另一个数组中的相应索引值不匹配,则这两个集合不相同,所有线程都应该停止他们正在做的事情并继续下一组 4 个非常大的数组.这个过程一直持续到所有的数组集合对都被比较并被认为相等或不相等。当其中一个线程发现不匹配时,我希望所有线程都停止。实现这一点的正确方法是什么?

【问题讨论】:

  • 请记住,我想要最有效的解决方案。我希望在最短的时间内将所有数组集合对相互比较。
  • 它们必须是数组吗?我可以想象有一些方法可以索引数组以加快比较速度。
  • 另外,注意数组中的元素不是 volatile stackoverflow.com/questions/2236184/…

标签: java arrays multithreading events concurrency


【解决方案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

现在,每个 MyThread 中的 run() 方法将具有类似的内容

if (terminationEvent.terminated) {
    break;
}

在循环中,并在其他线程需要停止时设置terminationEvent.terminated = true;

(通常我不会使用像 terminated 这样的公共字段,但你说你想要效率。我认为这比 getter 方法更有效,但我没有尝试过任何基准测试。另外,在像这样的简单案例,我认为您不必担心线程读取或写入terminated 字段时的同步。)

【讨论】:

    【解决方案2】:

    停止其他线程通常通过使用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();
    }
    

    【讨论】:

    • 这可能是一种解决方案,但我怀疑它是“通常”完成的方式。
    • 但是每个线程都必须轮询以查看是否发生了中断。线程花在轮询上的时间越多,它们完成的比较就越少。
    • 有没有比每次 X 比较后让每个线程轮询更有效的解决方案?
    • 恐怕 Java 目前不提供任何(安全的)替代方案。但是,检查每 10 次比较并不是对性能的主要影响。我同意它看起来不太理想,但至少它是一种保证运行时一致性的安全方式。
    • @SachaTRed 没有不涉及某种投票的答案。
    【解决方案3】:

    使用 volatile 变量设置中止条件。在由所有线程运行的检查循环中,让这些线程不间断地检查 N 个值,这样它们就不必过于频繁地获取 volatile,与值匹配测试相比,这可能代价高昂。对您的解决方案进行基准测试,以在您的目标硬件上找到 N 的最佳值。

    另一种方法是使用 ForkJoin 方法,如果发现不匹配,则结果为真。将您的数组切片划分为类似于 N 的最小大小。

    【讨论】:

    • 我没有想过在数组集上使用 ForkJoin。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 2014-05-05
    相关资源
    最近更新 更多