Java 多线程概念和 join() 方法

我对Java中线程中使用的方法感到困惑。在下面的代码中:join()

// Using join() to wait for threads to finish.
class NewThread implements Runnable {

    String name; // name of thread
    Thread t;

    NewThread(String threadname) {
        name = threadname;
        t = new Thread(this, name);
        System.out.println("New thread: " + t);
        t.start(); // Start the thread
    }
// This is the entry point for thread.

    public void run() {
        try {
            for (int i = 5; i > 0; i--) {
                System.out.println(name + ": " + i);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println(name + " interrupted.");
        }
        System.out.println(name + " exiting.");
    }
}

class DemoJoin {

    public static void main(String args[]) {
        NewThread ob1 = new NewThread("One");
        NewThread ob2 = new NewThread("Two");
        NewThread ob3 = new NewThread("Three");
        System.out.println("Thread One is alive: "
                + ob1.t.isAlive());
        System.out.println("Thread Two is alive: "
                + ob2.t.isAlive());
        System.out.println("Thread Three is alive: "
                + ob3.t.isAlive());
// wait for threads to finish
        try {
            System.out.println("Waiting for threads to finish.");
            ob1.t.join();
            ob2.t.join();
            ob3.t.join();
        } catch (InterruptedException e) {
            System.out.println("Main thread Interrupted");
        }
        System.out.println("Thread One is alive: "
                + ob1.t.isAlive());
        System.out.println("Thread Two is alive: "
                + ob2.t.isAlive());
        System.out.println("Thread Three is alive: "
                + ob3.t.isAlive());
        System.out.println("Main thread exiting.");
    }
}

此程序的示例输出如下所示:

New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
New thread: Thread[Three,5,main]
Thread One is alive: true
Thread Two is alive: true
Thread Three is alive: true
Waiting for threads to finish.
One: 5
Two: 5
Three: 5
One: 4
Two: 4
Three: 4
One: 3
Two: 3
Three: 3
One: 2
Two: 2
Three: 2
One: 1
Two: 1
Three: 1
Two exiting.
Three exiting.
One exiting.
Thread One is alive: false
Thread Two is alive: false
Thread Three is alive: false
Main thread Exiting

在上面的代码中:

  1. 我无法理解程序的执行流程,并且当创建时,构造函数被调用,但仍然不执行方法,而是继续执行方法。那么,为什么会发生这种情况呢?ob1t.start()run()main()

  2. join()方法用于等待,直到调用它的线程不终止,但是在输出中,我们看到线程的备用输出为什么??

如果使用是这个,那么有什么用??joinsynchronized

我知道我在这里缺少一个基本概念,但我无法弄清楚,所以请帮忙。


答案 1

你必须明白,线程调度是由线程调度程序控制的。因此,在正常情况下,您无法保证线程的执行顺序。

但是,您可以使用 等待线程完成其工作。join()

例如,在您的情况下

ob1.t.join();

在线程完成运行之前,此语句不会返回。t

试试这个,

class Demo {
   Thread t = new Thread(
                 new Runnable() {
                     public void run () {
                         //do something
                     }
                  }
    );
    Thread t1 = new Thread(
                 new Runnable() {
                     public void run () {
                         //do something
                     }
                  }
    );
    t.start(); // Line 15
    t.join();  // Line 16
    t1.start();
}

在上面的示例中,您的主线程正在执行。当它遇到第 15 行时,线程 t 在线程调度程序中可用。一旦主线程到达第 16 行,它将等待线程完成。t

注意:对线程或线程 不执行任何操作。它只影响调用它的线程(即线程)。t.jointt1main()

编辑:

t.join();需要位于块内,因为它是异常,否则您将在编译时收到错误。所以,它应该是:trythrowsInterruptedException

try{
    t.join();
}catch(InterruptedException e){
    // ...
}

答案 2

首先,当您创建时,将调用构造函数并开始执行。当时也在单独的线程中运行。请记住,创建新线程时,它与主线程并行运行。这就是为什么主用下一个语句再次开始执行的原因。ob1t.start()

语句用于防止子线程成为孤立线程。这意味着,如果您没有在主类中调用,则主线程将在执行后退出,并且子线程仍将在那里执行语句。 将等到所有子线程完成其执行,然后只有 main 方法将退出。Join()join()Join()

阅读本文,帮助很大。