我有一些关于多线程的问题。我的计划如下:
...
for(int i=0; i< 10; i++)
{
new Thread(){
@Overried
public void run(){
<do something level 1>
<do something level 2>
}
}.start;
}
<do something level 3>
...
我希望主线程只在所有10个线程完成[执行第2级]之后执行[执行第3级]。并且在所有子线程完成[执行某个级别1]的事件发生之前,没有任何线程执行[执行第2级]。
答案 0 :(得分:3)
您应该保留对您开始的主题的引用,以便在其上调用join
。
要做到第一件事,你可以这样做:
Thread[] threads = new Thread[10];
for(int i=0; i< 10; i++)
{
threads[i] = new Thread(){
// ...
};
threads[i].start();
}
for(int i=0; i< 10; i++)
{
threads[i].join();
}
对于第二个,您应该在主线程中使用wait
,在子线程中使用notify
(在完成任务1之后)以指示第一部分的结束,然后{{1在主线程上的子线程和wait
上,表示所有线程完成了第一部分。
答案 1 :(得分:0)
我建议你在两个街区中分解[do level 1]
和[do level 2]
。
类似
...
for(int i=0; i< 10; i++)
{
new Thread(){
public void run(){
<do something level 1>
}
}.start;
}
**join**
for(int i=0; i< 10; i++)
{
new Thread(){
public void run(){
<do something level 2>
}
}.start;
}
<do something level 3>
...
而不是使用主线程中的计数器与wait
\ notify
一起使用。可能只是因为我对这些人感到不舒服,但我相信它会使事情变得不必要地复杂,你几乎肯定会遇到竞争条件。
我还建议您使用ExecutorService
抽象而不是使用Thread
。它们消除了在最低级别工作的需要,并且具有很强的可配置性和强大性。一旦你习惯了它们,它们也很容易理解。
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 1; i <= 10; i++) {
final int w = i;
service.execute(new Runnable() {
public void run() {
long wait = (long) (Math.random() * 1000);
try {
Thread.sleep(wait);
} catch (InterruptedException e) {
}
System.out.println(w + "LEVEL 1 done " + wait);
}
});
}
service.shutdown();
service.awaitTermination(1, TimeUnit.DAYS);
System.out.println("all level 1 done");
service = Executors.newFixedThreadPool(10);
for (int i = 1; i <= 10; i++) {
final int w = i;
service.execute(new Runnable() {
public void run() {
long wait = (long) (Math.random() * 1000);
try {
Thread.sleep(wait);
} catch (InterruptedException e) {
}
System.out.println(w + "LEVEL 2 done " + wait);
}
});
}
service.shutdown();
service.awaitTermination(1, TimeUnit.DAYS);
System.out.println("all done");