【问题标题】:using .join() for a group of threads gives rise to an unexpected result对一组线程使用 .join() 会导致意外结果
【发布时间】:2014-06-24 11:46:47
【问题描述】:

我需要同时执行一组线程并等待它们完成,然后再恢复主线程。这是我的自定义类 MyRunnable:

 Class MyRunnable implements Runnable{
       int value;
       MyRunnable(int value){
          this.value = value;
       }
       @Override
       public void run(){
          System.out.println("Started thread " + value);
          System.out.println("Finished thread " + value);
       }
    }
    Thread[] myThreads;
    int total = 25;
    int size = 5;

    while(total > 0){
       total -= 5;
       size = 5;
       myThreads = new Thread[size];

       for(int i = 0; i < size; i++){
          myThreads[i] = new Thread(new MyRunnable (i));
       }
       for(Thread t:myThreads){
          T.start()j
       }
       for(Thread t:myThreads){
          try{
             t.join();
          } catch(InterruptedException ex) {
             System.out.println("error");
          }
       }
       System.out.println("set finished");
    }

我需要一组五个线程一次执行,并且主线程只有在所有线程都完成执行后才能继续。上面的代码不起作用,因为对 .join 的调用似乎被忽略了。我还尝试给组中的每个线程一个随机的睡眠时间,以查看意外结果是否是由于线程完成的速度比调用 .join() 的速度更快。结果还是一样。

【问题讨论】:

  • 是什么阻止你在这里使用Executor
  • 实际启动线程的代码行中有两个拼写错误,所以我怀疑这不是您的实际代码,并且您的真实版本中有一些我们不知道的错误。
  • 我喜欢“Class”的定义...从 MS Word 复制粘贴?
  • for(Thread t:myThreads){T.start()j} -> for(Thread t:myThreads){t.start();}
  • 我对代码进行了更正。它缺少一个主要方法。

标签: java multithreading


【解决方案1】:

我进行了调整(在每个 join 调用之后添加一个 println),编译并运行了您的应用程序,但我没有看到 join 被跳过的证据。代码和输出如下。

代码:

package test;

public class ThreadTest {

    static class MyRunnable implements Runnable {
        int value;

        MyRunnable(int value) {
            this.value = value;
        }

        @Override
        public void run() {
            System.out.println("Started thread " + value);
            System.out.println("Finished thread " + value);
        }
    }

    public static void main(String[] args) {
        Thread[] myThreads;
        int total = 25;
        int size = 5;

        while (total > 0) {
            total -= 5;
            size = 5;
            myThreads = new Thread[size];

            for (int i = 0; i < size; i++) {
                myThreads[i] = new Thread(new MyRunnable(i));
            }
            for (Thread t : myThreads) {
                t.start();
            }
            for (Thread t : myThreads) {
                try {
                    t.join();
                    System.out.println("joined");
                } catch (InterruptedException ex) {
                    System.out.println("error");
                }
            }
            System.out.println("set finished");
        }
    }
}

输出:

Started thread 0
Finished thread 0
Started thread 2
Started thread 1
Finished thread 1
Finished thread 2
Started thread 3
Finished thread 3
joined
joined
joined
joined
Started thread 4
Finished thread 4
joined
set finished
Started thread 0
Started thread 1
Started thread 2
Finished thread 2
Started thread 3
Finished thread 0
Finished thread 3
Finished thread 1
joined
joined
joined
joined
Started thread 4
Finished thread 4
joined
set finished
Started thread 0
Finished thread 0
Started thread 1
Started thread 2
Finished thread 1
Finished thread 2
joined
Started thread 4
Finished thread 4
Started thread 3
joined
joined
Finished thread 3
joined
joined
set finished
Started thread 0
Started thread 3
Finished thread 3
Started thread 4
Started thread 1
Started thread 2
Finished thread 1
Finished thread 4
Finished thread 0
Finished thread 2
joined
joined
joined
joined
joined
set finished
Started thread 0
Started thread 1
Finished thread 0
Finished thread 1
Started thread 2
Finished thread 2
Started thread 4
joined
joined
joined
Started thread 3
Finished thread 4
Finished thread 3
joined
joined
set finished

【讨论】:

  • 我也没有看到这个问题。 :)
  • 我发现了问题。我错误地使用 System.err 而不是 System.out 来打印“设置完成”字符串。在我的情况下,结果看起来好像 .join 被忽略了。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 1970-01-01
  • 2015-09-03
  • 2014-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多