不能在Java中的多线程中使用join()

时间:2012-10-20 03:12:25

标签: java multithreading

我有一些关于多线程的问题。我的计划如下:

...
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级]。

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");