要解决单个结果的Java线程池

要解决单个结果的Java线程池,java,multithreading,threadpool,Java,Multithreading,Threadpool,给定一组不相等的输入值(某些输入可能比其他输入更容易求解),如何实现多线程方法来查找单个答案(在基于一个“正确”输入的一个线程中) 例如,使用多个线程查找并返回这些数组中的给定字母 (显然,实际程序中的数据集较大) 一旦找到了目标元素,就需要将其从线程返回到调用函数(父线程),并且可以终止所有其他线程 我考虑过的事情: 使用线程池(“常规”线程、执行器线程)运行并设置调用函数(公共变量)中的返回值 循环屏障阻止主线程直到找到答案在工作线程中添加对控制器的引用(控制器保存所有线程的列表) 控制器有

给定一组不相等的输入值(某些输入可能比其他输入更容易求解),如何实现多线程方法来查找单个答案(在基于一个“正确”输入的一个线程中)

例如,使用多个线程查找并返回这些数组中的给定字母 (显然,实际程序中的数据集较大)

一旦找到了目标元素,就需要将其从线程返回到调用函数(父线程),并且可以终止所有其他线程

我考虑过的事情:

使用线程池(“常规”线程、执行器线程)运行并设置调用函数(公共变量)中的返回值


循环屏障阻止主线程直到找到答案

在工作线程中添加对控制器的引用(控制器保存所有线程的列表)


控制器有一个方法来通知已找到结果,该方法存储结果并终止/中断所有线程。

在工作线程中添加对控制器的引用(控制器保存所有线程的列表)


控制器有一个方法来通知已找到结果,该方法存储结果并终止/中断所有线程。

不知何故,正在查找结果的线程需要检查是否已找到结果。他们可以通过被中断然后检查中断标志(任何抛出InyerRuptedException的方法都会执行此检查)来完成此操作

他们还可以通过查看其他一些状态(如结果队列或条件变量)进行检查

例如:

while (resultQueue.isEmpty()) {
    do a small amount of work
}
要检查中断状态,请执行以下操作:

while (!Thread.interrupted()) {
    do a small amount of work
}

不知何故,寻找结果的线程需要检查结果是否已找到。它们可以通过被中断然后检查中断标志(任何抛出InyerRuptedException的方法都会执行此检查)来完成此操作

他们还可以通过查看其他一些状态(如结果队列或条件变量)进行检查

例如:

while (resultQueue.isEmpty()) {
    do a small amount of work
}
要检查中断状态,请执行以下操作:

while (!Thread.interrupted()) {
    do a small amount of work
}

您可以使用其他任务共享和轮询的答案设置AtomicReference,以查看它们是否应该停止。您还可以使用它通知()等待的线程

final AtomicReference result = ...
// adds tasks
synchronized(result) {
    while(result.get() == null)
          result.wait();
}

// to check there is no answer. It doesn't have to be synchronized 
// as the value is thread safe.
while(result.get() == null) {


// in the task when a result is found.
synchronized(result) {
    result.set(answer);
    result.notifyAll();
}

我会使用ExecutorService。

您可以使用其他任务共享和轮询的答案设置原子引用,以查看它们是否应该停止。您还可以使用它通知()等待的线程

final AtomicReference result = ...
// adds tasks
synchronized(result) {
    while(result.get() == null)
          result.wait();
}

// to check there is no answer. It doesn't have to be synchronized 
// as the value is thread safe.
while(result.get() == null) {


// in the task when a result is found.
synchronized(result) {
    result.set(answer);
    result.notifyAll();
}

我会使用ExecutorService。

您可以使用ExecutorCompletionService处理找到的结果。 一旦得到想要的结果,请取消剩余的任务

我喜欢这种方法的原因是任务仍然很简单。他们只需要知道如何完成工作,并检测何时取消任务


然后,任务的创建者处理处理结果并确定何时取消剩余的工作。

您可以使用ExecutorCompletionService处理找到的结果。 一旦得到想要的结果,请取消剩余的任务

我喜欢这种方法的原因是任务仍然很简单。他们只需要知道如何完成工作,并检测何时取消任务


然后,任务的创建者处理处理结果并确定何时取消剩余的工作。

我更喜欢自己完成。这提供了更好的机会来搞糟事情,但也更灵活。我从控制字段开始:

public volatile boolean  foundIt = false;
public final boolean[]   jobList = { true, true, ..., true };
public final Object      threadLock = new Object();
public final Object      controllerLock = new Object();
(它们实际上不应该是公共的;为它们提供您可以管理的最低可视性。)然后启动每个线程,让每个线程知道搜索哪个数组,以及完成后应该关闭哪个布尔值(
索引,如下)。使用以下命令暂停控制器:

synchronized (controllerLock)  { controllerLock.wait(); }
线程中的Runnable应该定期检查
foundIt
以确保它仍然为false。如果为true,它应该关闭。不需要同步。在查找答案时,搜索代码应该执行如下操作:

haveAnswer:  {
    if (foundIt)  break haveAnswer;   // Already found by another thread.
    synchronized (threadLock)  {
        // Only one thread at a time can get into this block.
        if (foundIt)  break haveAnswer;   // Found since previous check.
        foundIt = true;
    }
    // Add code here to put answer in right place.
    // Only one thread will get this far.
}
关闭时,无论是点击搜索数组的末尾,注意到
foundIt
为真,还是找到答案,请以以下内容结束:

synchronized (controllerLock)  {
    jobList[index] = false;    // Tell world this thread is done.
    for (boolean active : jobList)
        if (active)
            // Another thread is still running.
            return;
    // This was the last thread. We're done. Restart controller.
    controllerLock.notifyAll();
}

我更喜欢自己做。它提供了更好的机会来搞糟事情,但也更灵活。我从控制字段开始:

public volatile boolean  foundIt = false;
public final boolean[]   jobList = { true, true, ..., true };
public final Object      threadLock = new Object();
public final Object      controllerLock = new Object();
(它们实际上不应该是公共的;为它们提供您可以管理的最低可视性。)然后启动每个线程,让每个线程知道搜索哪个数组,以及完成后应该关闭哪个布尔值(
索引,如下)。使用以下命令暂停控制器:

synchronized (controllerLock)  { controllerLock.wait(); }
线程中的Runnable应该定期检查
foundIt
以确保它仍然为false。如果为true,它应该关闭。不需要同步。在查找答案时,搜索代码应该执行如下操作:

haveAnswer:  {
    if (foundIt)  break haveAnswer;   // Already found by another thread.
    synchronized (threadLock)  {
        // Only one thread at a time can get into this block.
        if (foundIt)  break haveAnswer;   // Found since previous check.
        foundIt = true;
    }
    // Add code here to put answer in right place.
    // Only one thread will get this far.
}
关闭时,无论是点击搜索数组的末尾,注意到
foundIt
为真,还是找到答案,请以以下内容结束:

synchronized (controllerLock)  {
    jobList[index] = false;    // Tell world this thread is done.
    for (boolean active : jobList)
        if (active)
            // Another thread is still running.
            return;
    // This was the last thread. We're done. Restart controller.
    controllerLock.notifyAll();
}

因此,让控制器保留所有线程的列表,并在子线程中找到答案后,将值存储在控制器中。控制器正在轮询要更新的值(infinte thread.sleep-check loop?)并在更新时杀死所有子线程?也可以这样做,但如果可以避免,我反对轮询。只要让控制器有一个方法(比如
valueFound())
然后,找到解决方案的线程调用它。然后,从这个方法,控制器杀死所有剩余的线程。好的,我需要调用方法返回“answer”值,尽管程序是结构化的,因此有人调用findanswer()和该函数(当前是单线程的)然后会产生几个线程来找到答案,并返回给它一些东西,让控制器保留所有线程的列表,一旦在子线程中找到答案,