Java中的线程等待和协调

在Java中,线程是并发编程的核心概念之一。在某些情况下,我们可能需要一个线程等待另外两个线程完成后再继续执行。本文将介绍如何在Java中实现这种线程等待和协调的机制,并提供相应的代码示例。

1. 线程的基本概念和使用方法

在开始之前,我们先来回顾一下线程的基本概念和使用方法。

线程是进程中的一个独立执行单元,每个进程可以包含多个线程。线程可以并发执行,让多个任务同时进行,从而提高程序的执行效率。在Java中,线程是通过Thread类来表示的。

创建一个线程的常用方法有两种:继承Thread类和实现Runnable接口。下面是一个通过继承Thread类创建线程的示例代码:

public class MyThread extends Thread {
    public void run() {
        // 线程执行的代码逻辑
    }
}

通过实现Runnable接口创建线程的示例代码如下:

public class MyRunnable implements Runnable {
    public void run() {
        // 线程执行的代码逻辑
    }
}

在创建线程后,可以通过调用start()方法来启动线程,线程会自动执行run()方法中的代码逻辑。

2. 线程的等待和协调机制

在实际的应用中,有时候我们需要一个线程等待另外两个线程完成后再继续执行。Java提供了多种机制来实现线程的等待和协调,包括使用join()方法、wait()和notify()方法以及使用CountDownLatch和CyclicBarrier等类。

2.1 使用join()方法

join()方法是Thread类提供的一个方法,可以让一个线程等待另一个线程执行完成后再继续执行。下面是一个使用join()方法的示例代码:

public class ThreadJoinExample {
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new MyRunnable());
        Thread thread2 = new Thread(new MyRunnable());
        
        thread1.start();
        thread2.start();
        
        thread1.join();
        thread2.join();
        
        // 线程1和线程2执行完成后,继续执行的代码逻辑
    }
}

在上面的代码中,线程thread1和线程thread2分别执行MyRunnable类中的run()方法。通过调用thread1.join()和thread2.join(),主线程会等待thread1和thread2执行完成后再继续执行。

2.2 使用wait()和notify()方法

wait()和notify()方法是Object类提供的两个方法,用于实现线程的等待和唤醒机制。一个线程可以调用wait()方法进入等待状态,直到另一个线程调用notify()方法唤醒它。下面是一个使用wait()和notify()方法的示例代码:

线程1:

synchronized (sharedObject) {
    while (condition) {
        sharedObject.wait();
    }
}

线程2:

synchronized (sharedObject) {
    // 执行线程2的代码逻辑
    sharedObject.notify();
}

在上面的代码中,线程1在一个共享对象上调用wait()方法,如果条件满足,线程1会一直等待。线程2在相同的共享对象上调用notify()方法,唤醒等待的线程1。

2.3 使用CountDownLatch和CyclicBarrier

CountDownLatch和CyclicBarrier是Java提供的两个用于线程等待和协调的类。

CountDownLatch是一个同步辅助类,可以使一个或多个线程等待其他线程完成后再继续执行。下面是一个使用CountDownLatch的示例代码:

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(2);
        
        Thread thread1 = new Thread(new MyRunnable(latch));
        Thread thread2 = new Thread(new MyRunnable(latch));
        
        thread1.start();
        thread2.start();
        
        latch.await();
        
        // 线程1和线程2执行完成