Java 简明教程

Java - Joining Threads

创建 Thread 对象后,可以通过调用 start() method 开始该对象,这会执行对 run() method 的调用。在运行多个线程的情况下,我们可以阻止当前线程,直到另一个线程终止为止。

Once a Thread object is created, you can start it by calling start() method, which executes a call to run() method. With multiple threads running, we can block current thread until another thread terminates.

Joining Threads in Java

在 Java 中联接线程指的是在另一个线程完成执行之前等待(或阻塞)线程。 Thread class 的 join() 方法用于此目的。

Joining threads in Java refers for waiting (or, blocking) a thread until another thread finishes its execution. The join() method of the Thread class is used for this purpose.

Syntax

以下是 join() 方法的简单语法 -

Following is a simple syntax of join() method −

void join();

Overloaded Thread.join() Methods

以下是三个重载的 join() 方法 -

The following are the three overloaded join() method -

  1. join() − The current thread invokes this method on a second thread, causing the current thread to block until the second thread terminates.

  2. join(long millisec) − The current thread invokes this method on a second thread, causing the current thread to block until the second thread terminates or the specified number of milliseconds passes.

  3. join(long millisec, int nanos) − The current thread invokes this method on a second thread, causing the current thread to block until the second thread terminates or the specified number of milliseconds + nanoseconds passes.

Example of Joining Threads in Java

在此示例中,我们将通过实现 Runnable 接口来创建一个类 RunnableDemo。RunnableDemo 类有 run() 方法实现。在主类 TestThread 中,我们创建了 RunnableDemo 对象,并利用这些对象创建了两个 Thread 对象。在每个线程对象上调用 Thread.start() 方法时,线程开始处理,并执行程序。使用 join() 方法,我们阻塞了当前线程,以确保只有在一个线程完成后,才开始下一个线程。

In this example, we’re creating a class RunnableDemo by implementing Runnable interface. RunnableDemo class has run() method implementation. In main class TestThread, we’ve created the RunnableDemo objects and using those objects we’ve created two Thread objects. When Thread.start() method is called on each thread objects, threads start processing and program is executed. Using join() method, we’re blocking the current thread which ensure that once thread is complete then only next thread will start.

package com.tutorialspoint;

class RunnableDemo implements Runnable {
   RunnableDemo( ) {
      System.out.println("Thread: " + Thread.currentThread().getName() + ", " + "State: New");
   }

   public void run() {
      System.out.println("Thread: " + Thread.currentThread().getName() + ", " + "State: Running");
      for(int i = 4; i > 0; i--) {
         System.out.println("Thread: " + Thread.currentThread().getName() + ", " + i);
      }
      System.out.println("Thread: " + Thread.currentThread().getName() + ", " + "State: Dead");
   }
}

public class TestThread {
   public static void main(String args[]) throws InterruptedException {
      Thread t1 = new Thread( new RunnableDemo(), "Thread-1");
      Thread t2 = new Thread( new RunnableDemo(), "Thread-2");
      Thread t3 = new Thread( new RunnableDemo(), "Thread-3");
      // start t1 thread and join main thread
      t1.start();
      t1.join();
      // t2 will start when t1 is dead
      t2.start();
      t2.join();
      // t3 will start when t2 is dead
      t3.start();
   }
}
Thread: Thread-1, State: New
Thread: Thread-2, State: New
Thread: Thread-1, State: Running
Thread: Thread-1, 4
Thread: Thread-1, 3
Thread: Thread-1, 2
Thread: Thread-1, 1
Thread: Thread-1, State: Dead
Thread: Thread-2, State: Running
Thread: Thread-2, 4
Thread: Thread-2, 3
Thread: Thread-2, 2
Thread: Thread-2, 1
Thread: Thread-2, State: Dead

More Example of Joining Threads in Java

Example 1

在此示例中,我们将通过实现 Runnable 接口来创建一个类 RunnableDemo。RunnableDemo 类有 run() 方法实现。在主类 TestThread 中,我们创建了 RunnableDemo 对象,并利用这些对象创建了两个 Thread 对象。在每个线程对象上调用 Thread.start() 方法时,线程开始处理,并执行程序。使用 join(long millisec) 方法,我们阻塞当前线程 200 毫秒,以确保只有在一个线程完成后或经过 200 毫秒延迟后,才开始下一个线程。

In this example, we’re creating a class RunnableDemo by implementing Runnable interface. RunnableDemo class has run() method implementation. In main class TestThread, we’ve created the RunnableDemo objects and using those objects we’ve created two Thread objects. When Thread.start() method is called on each thread objects, threads start processing and program is executed. Using join(long millisec) method, we’re blocking the current thread for 200 millisecs which ensure that once thread is complete or a delay of 200 ms occurred then only next thread will start.

package com.tutorialspoint;

class RunnableDemo implements Runnable {
   RunnableDemo( ) {
      System.out.println("Thread: " + Thread.currentThread().getName() + ", " + "State: New");
   }

   public void run() {
      System.out.println("Thread: " + Thread.currentThread().getName() + ", " + "State: Running");
      for(int i = 4; i > 0; i--) {
         try {
            Thread.sleep(50);
         } catch (InterruptedException e) {
            // TODO Auto-generated catch block
         e.printStackTrace();
         }
         System.out.println("Thread: " + Thread.currentThread().getName() + ", " + i);
      }
      System.out.println("Thread: " + Thread.currentThread().getName() + ", " + "State: Dead");
   }
}

public class TestThread {
   public static void main(String args[]) throws InterruptedException {
      Thread t1 = new Thread( new RunnableDemo(), "Thread-1");
      Thread t2 = new Thread( new RunnableDemo(), "Thread-2");
      Thread t3 = new Thread( new RunnableDemo(), "Thread-3");
      // start t1 thread and join main thread
      t1.start();
      t1.join(200);
      // t2 will start when t1 is dead or 200 ms is elapsed
      t2.start();
      t2.join(200);
      // t3 will start when t2 is dead or 200 ms is elapsed
      t3.start();
   }
}
Thread: main, State: New
Thread: main, State: New
Thread: main, State: New
Thread: Thread-1, State: Running
Thread: Thread-1, 4
Thread: Thread-1, 3
Thread: Thread-1, 2
Thread: Thread-2, State: Running
Thread: Thread-1, 1
Thread: Thread-1, State: Dead
Thread: Thread-2, 4
Thread: Thread-2, 3
Thread: Thread-2, 2
Thread: Thread-3, State: Running
Thread: Thread-2, 1
Thread: Thread-2, State: Dead
Thread: Thread-3, 4
Thread: Thread-3, 3
Thread: Thread-3, 2
Thread: Thread-3, 1
Thread: Thread-3, State: Dead

Example 2

在此示例中,我们将通过实现 Runnable 接口来创建一个类 RunnableDemo。RunnableDemo 类有 run() 方法实现。在主类 TestThread 中,我们创建了 RunnableDemo 对象,并利用这些对象创建了两个 Thread 对象。在每个线程对象上调用 Thread.start() 方法时,线程开始处理,并执行程序。使用 join(long millisec, long nanoseconds) 方法,我们阻塞当前线程 200 毫秒和 100000 纳秒,以确保只有在一个线程完成后或经过 201 毫秒延迟后,才开始下一个线程。

In this example, we’re creating a class RunnableDemo by implementing Runnable interface. RunnableDemo class has run() method implementation. In main class TestThread, we’ve created the RunnableDemo objects and using those objects we’ve created two Thread objects. When Thread.start() method is called on each thread objects, threads start processing and program is executed. Using join(long millisec, long nanoseconds) method, we’re blocking the current thread for 200 millisecs and 100000 nanosecs which ensure that once thread is complete or a delay of 201 ms occurred then only next thread will start.

package com.tutorialspoint;

class RunnableDemo implements Runnable {
   RunnableDemo( ) {
      System.out.println("Thread: " + Thread.currentThread().getName() + ", " + "State: New");
   }

   public void run() {
      System.out.println("Thread: " + Thread.currentThread().getName() + ", " + "State: Running");
      for(int i = 4; i > 0; i--) {
         try {
            Thread.sleep(49);
         } catch (InterruptedException e) {
            // TODO Auto-generated catch block
         e.printStackTrace();
         }
         System.out.println("Thread: " + Thread.currentThread().getName() + ", " + i);
      }
      System.out.println("Thread: " + Thread.currentThread().getName() + ", " + "State: Dead");
   }
}

public class TestThread {
   public static void main(String args[]) throws InterruptedException {
      Thread t1 = new Thread( new RunnableDemo(), "Thread-1");
      Thread t2 = new Thread( new RunnableDemo(), "Thread-2");
      Thread t3 = new Thread( new RunnableDemo(), "Thread-3");

      // start t1 thread and join main thread
      t1.start();
      t1.join(200,100000);

      // t2 will start when t1 is dead or 201 ms is elapsed
      t2.start();
      t2.join(200,100000);

      // t3 will start when t2 is dead or 201 ms is elapsed
      t3.start();
   }
}
Thread: main, State: New
Thread: main, State: New
Thread: main, State: New
Thread: Thread-1, State: Running
Thread: Thread-1, 4
Thread: Thread-1, 3
Thread: Thread-1, 2
Thread: Thread-1, 1
Thread: Thread-1, State: Dead
Thread: Thread-2, State: Running
Thread: Thread-2, 4
Thread: Thread-2, 3
Thread: Thread-2, 2
Thread: Thread-2, 1
Thread: Thread-2, State: Dead
Thread: Thread-3, State: Running
Thread: Thread-3, 4
Thread: Thread-3, 3
Thread: Thread-3, 2
Thread: Thread-3, 1
Thread: Thread-3, State: Dead