Thread.join() 方法用于等待线程执行完成。在使用 Thread.join() 时,为了确保线程安全,可以使用同步辅助类,如 synchronized 关键字、Lock 接口或 ReentrantLock 类等。
以下是一些使用同步辅助类的示例:
synchronized 关键字:class MyRunnable implements Runnable {
    @Override
    public void run() {
        synchronized (lock) {
            // 临界区代码
        }
    }
}
public class Main {
    private static final Object lock = new Object();
    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(); // 等待 thread1 执行完成
        thread2.join(); // 等待 thread2 执行完成
    }
}
Lock 接口:import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class MyRunnable implements Runnable {
    private final Lock lock = new ReentrantLock();
    @Override
    public void run() {
        lock.lock(); // 获取锁
        try {
            // 临界区代码
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}
public class Main {
    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(); // 等待 thread1 执行完成
        thread2.join(); // 等待 thread2 执行完成
    }
}
ReentrantLock 类:import java.util.concurrent.locks.ReentrantLock;
class MyRunnable implements Runnable {
    private final ReentrantLock lock = new ReentrantLock();
    @Override
    public void run() {
        lock.lock(); // 获取锁
        try {
            // 临界区代码
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}
public class Main {
    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(); // 等待 thread1 执行完成
        thread2.join(); // 等待 thread2 执行完成
    }
}
在这些示例中,我们使用了不同的同步辅助类来确保在多线程环境下对共享资源的访问是线程安全的。