【问题标题】:How the join() method in Java works?Java 中的 join() 方法是如何工作的?
【发布时间】:2014-05-06 02:27:46
【问题描述】:
class JoinDemo extends Thread {
    JoinDemo(String nm) {
        setName(nm);
        start();
    }
    public void run() {
        for (int i = 1; i <= 5; i++) {
            try {
                Thread.sleep(100);
            } catch (Exception e) {
                System.out.println(e);
            }
            System.out.println(i);
        }
        System.out.println(getName() + " exiting.");
    }
    public static void main(String args[]) {
        JoinDemo t1 = new JoinDemo("One");
        JoinDemo t2 = new JoinDemo("Two");
        JoinDemo t3 = new JoinDemo("Three");

        try {
            t1.join();
        } catch (Exception e) {
            System.out.println(e);
        }
        System.out.println("Main Thread Exits now.");
    }
}

得到的输出是:

1
1
1
2
2
2
3
3
3
4
4
4
5
5
Three exiting.
One exiting.
5
Main Thread Exiting
Two exiting. 

我在浏览了各个网站了解Join()的概念后编写了上面的程序。但我仍然无法得到它。我面临的问题是我使用了 t1.join()。所以线程一应该在三个之前退出,但是这里线程三在一个之前退出。每次我运行程序时,输出都是不同的。有时是两个在一个之前退出,或者三个在一个之前退出。不应该在任何其他线程之前线程一个退出?由于 t1.join() 等待线程一在三和一之前终止??

【问题讨论】:

  • 寻求帮助时要做的第一件事是确保您的代码的格式和缩进可读。这次我已经为你做了。
  • 可能 t1 在到达 t1.join() 时已经完成。要获得效果可能会更改为 Thread.sleep(2000)。
  • stackoverflow.com/questions/18479771/… 这里问的几乎完全相同的问题,答案很好。
  • 您的代码中没有任何内容可以确保thread one should exit before three 线程一和三三之间有什么关系?实际上并不能保证线程一会在三三结束之前真正开始。

标签: java join


【解决方案1】:

不,你误会了join()的效果。

当您执行t1.join()时,您只是断言线程 t1 将在继续程序之前完成。

如您所见,这就是您所拥有的,

One exiting.
5
Main Thread Exiting

Main Thread Exiting 表示的主要结束前的一个出口。

如果您希望您的程序在完成之前完成所有线程,您应该这样做:

try {
        t1.join();
        t2.join();
        t3.join();
    } catch (Exception e) {
        System.out.println(e);
    }

如果你想要一个完成然后 2 然后 3

    JoinDemo t1 = new JoinDemo("One");
    try {
        t1.join();
    } catch (Exception e) { System.out.println(e); }

    JoinDemo t2 = new JoinDemo("Two");
    try {
        t2.join();
    } catch (Exception e) { System.out.println(e); }

    JoinDemo t3 = new JoinDemo("Three");
    try {
        t3.join();
    } catch (Exception e) { System.out.println(e); }

【讨论】:

  • 您的最后一个示例将有效地序列化这些线程的执行。相反,您可能想添加一个线程 2 加入线程 1 和线程 3 加入线程 2 的示例,但所有 3 个线程(几乎)同时启动。
  • 好吧,是不是我无法控制线程的完成,但可以控制主线程的执行。就像我可以控制我的主线程何时使用 join() 完成?
【解决方案2】:

要确切知道 join() 在做什么,

JoinDemo t1=new JoinDemo("One");
t1.join();
JoinDemo t2=new JoinDemo("Two");
JoinDemo t3=new JoinDemo("Three");

声明t1后调用方法看看。

join()方法会让已经初始化的线程先完成。所以其他Threads会等到那时。

【讨论】:

    【解决方案3】:

    t1.join() 只是确保您的主线程将阻塞直到t1 完成。与其他两个线程相比,您无法控制 t1 完成的速度。

    t1t2t3 受线程调度程序的支配。您在代码中的唯一保证是 t1 将在主线程之前完成。

    【讨论】:

      【解决方案4】:

      您正在运行 3 个不同的线程。每个线程使用的优先级或 CPU 数量取决于 java 实现,在某些情况下由操作系统完成。这就是为什么你会得到不同的输出。 Joins 使正在运行的线程等待,直到联合线程死亡。

      我想你想要这个输出:

         class JoinDemo extends Thread {
          JoinDemo(String nm) {
              setName(nm);
          }
          public void run() {
              for (int i = 1; i <= 5; i++) {
                  try {
                      Thread.sleep(100);
                  } catch (Exception e) {
                      System.out.println(e);
                  }
                  System.out.println(i);
              }
              System.out.println(getName() + " exiting.");
          }
          public static void main(String args[]) {
              JoinDemo t1 = new JoinDemo("One");
              JoinDemo t2 = new JoinDemo("Two");
              JoinDemo t3 = new JoinDemo("Three");
              try {            
                  t1.start();
                  t1.join();
                  t2.start();
                  t2.join();
                  t3.start();
                  t3.join();
      
              } catch (Exception e) {
                  System.out.println(e);
              }
              System.out.println("Main Thread Exits now.");
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-02
        • 1970-01-01
        • 1970-01-01
        • 2011-01-13
        • 1970-01-01
        • 2019-09-22
        • 1970-01-01
        • 2011-12-26
        相关资源
        最近更新 更多