目标是创建搜索方法,该方法返回首先在所有搜索线程中找到的指针的索引。当其中一个完成后,我需要停止所有线程。
逻辑是:有4个线程。第一个线程检查干草堆的第一个%25,第二个线程检查干草堆的%25-%50,依此类推。
我应该在其中一个人打印文本时立即停止,但我总是得到4个输出,因为所有4个人都在大海捞针中找到针。但是,我只想要一个输出。
示例输出:(下面的索引)
I found, it is: 622
I found, it is: 4072
I found, it is: 7519
I found, it is: 7264
这是SearcherThreat类的扩展线程
public class SearcherThread extends Thread {
// PROPERTIES
private int needle;
private int[] haystack;
private int start, end;
// CONSTRUCTOR
public SearcherThread(int needle, int[] haystack, int start, int end) {
this.needle = needle;
this.haystack = haystack;
this.start = start;
this.end = end;
}
@Override
public void run() {
for (int i = start; i < end && !isInterrupted(); ++i) {
if (haystack[i] == needle) {
System.out.println("I found, it is: " + i);
for (SearcherThread searcher : InterruptTest.searchers) {
searcher.interrupt();
}
}
}
}
}
这是包含main和threads
的类import java.util.ArrayList;
public class InterruptTest {
public static ArrayList<SearcherThread> searchers = new ArrayList<SearcherThread>();
public static void main(String[] args) throws InterruptedException {
int itemCount = 10000;
int[] haystack = new int[itemCount];
int domainSize = 1000;
for (int i = 0; i < itemCount; ++i)
haystack[i] = (int) (Math.random() * domainSize);
int needle = 10;
int numThreads = 4;
int numItemsPerThread = haystack.length / numThreads;
int extraItems = haystack.length - numItemsPerThread * numThreads;
for (int i = 0, start = 0; i < numThreads; ++i) {
int numItems = (i < extraItems) ? (numItemsPerThread + 1) : numItemsPerThread;
searchers.add(new SearcherThread(needle, haystack, start, start + numItems));
start += numItems;
}
for (SearcherThread searcher : searchers)
searcher.start();
}
}
答案 0 :(得分:4)
我得到了这个输出:
interrupt()
正如您所看到的,完成的线程数从一次运行到下一次不等。
我们这里有一场比赛。可能发生的是一个线程在启动之前完成并中断其他线程 。所以他们没有看到中断。 javadoc说:
&#34;中断非活动的线程无需任何效果。&#34;
另一种可能性是中断传播速度不够快。请注意,javadoc并未表示中断线程可立即看到(every? true? [])
=> true
(every? false? [])
=> true
(every? odd? [])
=> true
。
我无法想到一个解决方案,它不能否定多线程的好处。另一方面,在现实世界的用例中:
如果您测量的是当前测试中的实际加速比,则可能负。
总之,在更现实的测试中,您应该看到中断大部分时间都在 。这应该足够好了。 (无论何时,线程都不能足够快地中断以阻止它们找到次要结果。)
答案 1 :(得分:0)
这是死灵,但这可以帮助其他人。您可以使用Java内置的Executors。对于Java 8,它具有
这是一个示例,说明如何编写您的课程。我正在使用newFixedThreadPool(int nThreads)来匹配您在代码中所做的事情
import java.util.concurrent.Callable;
public class SearcherThread implements Callable<Object> {
// PROPERTIES
private int needle;
private int[] haystack;
private int start, end;
// CONSTRUCTOR
public SearcherThread(int needle, int[] haystack, int start, int end) {
this.needle = needle;
this.haystack = haystack;
this.start = start;
this.end = end;
}
@Override
public Object call() throws Exception {
for (int i = start; i < end ; ++i) {
if (haystack[i] == needle) {
return i;
}
}
Thread.sleep(5000);
return null;
}
}
和Test类
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class InterruptTest {
public static ArrayList<SearcherThread> searchers = new ArrayList<SearcherThread>();
public static void main(String[] args) throws InterruptedException, ExecutionException {
int itemCount = 10000;
int[] haystack = new int[itemCount];
int domainSize = 1000;
for (int i = 0; i < itemCount; ++i)
haystack[i] = (int) (Math.random() * domainSize);
int needle = 10;
int numThreads = 4;
int numItemsPerThread = haystack.length / numThreads;
int extraItems = haystack.length - numItemsPerThread * numThreads;
for (int i = 0, start = 0; i < numThreads; ++i) {
int numItems = (i < extraItems) ? (numItemsPerThread + 1) : numItemsPerThread;
searchers.add(new SearcherThread(needle, haystack, start, start + numItems));
start += numItems;
}
//Preferred to use Executors.newWorkStealingPool() instead
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
executor.shutdown();//shutdown when done
Object result = executor.invokeAny(searchers);//<------- right here lookie
System.out.println("I found, it is: "+result);
}
}
ExecutorService.invokeAny(List