0

我对多线程有一些问题。我的程序如下:

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

4

2 回答 2

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子线程中使用(在完成任务一之后)来表示第一部分的结束,然后wait在子线程和notifyAll主线程上使用来表示所有线程首先完成部分。

于 2012-10-20T03:15:50.810 回答
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抽象而不是使用Threads. 它们消除了在最低级别工作的需要,并且可配置性强且功能强大。一旦你习惯了它们,它们也更容易理解。

    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");
于 2012-10-20T04:33:39.717 回答