我需要实现一个搜索方法,它将搜索haystack并返回第一个创建的指针索引。
static int search(T needle,T [] haystack,int numThreads)
我的问题:如果其中一个线程找到结果,我怎么能停止所有线程? 例如:我正在搜索5,我在数组中有10个数字,如[2,4,5,6,1,4,5,8,9,3],并且有2个线程。因此,第一个线程将查找第一部分[0-5],第二个线程将搜索其他部分[5-10]。如果线程2首先启动并且发现结果比其他线程更快,它应该返回6并终止线程1和2.
答案 0 :(得分:2)
这样做的经典方法是在线程之间简单地共享数据,以便它们可以相互通信。换句话说,将一些标志值初始化为"未找到"在开始线程之前。
然后,当线程运行时,它们处理数组中的元素,直到它们的元素耗尽,或标志值已设置为"找到"。
在伪代码中,这可能是:
main():
global array = createArray(size = 10000, values = random)
global foundIndex = -1
global mutex = createMutex()
startThread(id = 1, func = threadFn, param = (0, 4999))
startThread(id = 2, func = threadFn, param = (5000, 9999))
waitFor(id = 1)
waitFor(id = 2)
print("Result is ", foundIndex)
threadFn(first, last):
for index in first through last inclusive:
if userSpecifiedCheckFound(array[index]):
mutex.lock()
if foundIndex == -1:
foundIndex = index
mutex.unlock()
return
mutex.lock()
localIndex = foundIndex
mutex.unlock()
if localIndex != -1:
return
您可以从中看到,该函数的每个实例都将设置共享数据,并在找到符合您要查找的条件的值时返回。如果另一个线程已经设置了共享数据,它将也返回(不设置共享数据),这意味着如果另一个线程已经找到了某些东西,它可以提前退出。
请记住,在这种情况下,需要保护共享数据foundIndex
免受同时更改,以免它被破坏。在伪代码中,我已经展示了如何使用低级互斥信号量来做到这一点。
在Java中,这意味着使用synchronized
来实现相同的效果。举例来说,以下代码设置了一些合适的测试数据,以便二十进制数组的第十六个单元符合搜索标准。
然后运行两个线程,每半个数据一个,直到找到该单元格。
public class TestProg extends Thread {
// Shared data.
static int [] sm_array = new int[20];
static int sm_foundIndex = -1;
// Each thread responsible for its own stuff.
private int m_id, m_curr, m_last;
public TestProg(int id, int first, int last) {
m_id = id;
m_curr = first;
m_last = last;
}
// Runnable: continue until someone finds it.
public void run() {
// Try all cells allotted to thread.
while (m_curr <= m_last) {
System.out.println(m_id + ": processing " + m_curr);
// If I find it first, save and exit.
if (sm_array[m_curr] != 0) {
synchronized(this) {
if (sm_foundIndex == -1) {
sm_foundIndex = m_curr;
System.out.println(m_id + ": early exit, I found it");
return;
}
}
}
// If someone else finds it, just exit.
synchronized(this) {
if (sm_foundIndex != -1) {
System.out.println(m_id + ": early exit, sibling found it");
return;
}
}
// Kludge to ensure threads run side-by-side.
try { Thread.sleep(100); } catch(Exception e) {}
m_curr++;
}
}
public static void main(String[] args) {
// Create test data.
for (int i = 0; i < 20; i++) {
sm_array[i] = 0;
}
sm_array[15] = 1;
// Create and start threads.
HelloWorld thread1 = new HelloWorld(1, 0, 9);
HelloWorld thread2 = new HelloWorld(2, 10, 19);
thread1.start();
thread2.start();
// Wait for both to finish, then print result.
try {
thread1.join();
thread2.join();
System.out.println("=> Result was " + sm_foundIndex);
} catch(Exception e) {
System.out.println("Interrupted: " + e);
}
}
}
该代码的输出(尽管线程使其有点不确定)是:
1: processing 0
2: processing 10
1: processing 1
2: processing 11
1: processing 2
2: processing 12
1: processing 3
2: processing 13
1: processing 4
2: processing 14
1: processing 5
2: processing 15
2: early exit, I found it
1: processing 6
1: early exit, sibling found it
=> Result was 15
答案 1 :(得分:0)
一旦第一个结果可用,您就可以查看ExecutorCompletionService,然后取消所有其他任务。
CompletionService
使用提供的Executor
执行任务和
将所有未来结果放在一个队列中,您可以从中按照完成顺序获取结果