给定一组不相等的输入值(某些输入可能比其他输入更容易解决),如何在查找单个答案时实现多线程方法(在一个线程中基于一个“正确”输入)
因此,例如,使用多个线程在这些数组中查找并返回给定的字母
(显然,在实际程序中具有较大的数据集)
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();
}