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

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

Inputs

[A, B, C, D, E, F]
[G, H]
[I, J, K]
[L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]


找到目标元素后,需要将其从线程返回给调用函数(父线程),并且可以杀死所有其他线程

我考虑过的事情:

使用线程池(“常规”线程,Executor线程)运行并在调用函数中设置返回值(公共变量?)

循环壁垒阻塞主线程,直到找到答案为止

最佳答案

我更喜欢自己做。它提供了更好的机会来解决问题,同时也提供了更大的灵活性。我将从控制字段开始:

public volatile boolean  foundIt = false;
public final boolean[]   jobList = { true, true, ..., true };
public final Object      threadLock = new Object();
public final Object      controllerLock = new Object();


(它们不应该真正公开;给它们提供您可以管理的最小可见性。)然后启动每个线程,让每个线程知道要搜索哪个数组,完成后应该关闭哪个布尔值(index,如下)。使用以下命令暂停控制器:

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();
}

10-04 20:35