java 线程协作与通信

发布时间 2023-05-24 16:03:21作者: 黄光跃

多个线程协作工作场景很多,比如保证线程执行的先后顺序,生产者消费者等

join()

public class Main {
    public static void main(String[] args) {
        ThreadA threadA = new ThreadA();
        ThreadB threadB = new ThreadB(threadA);
        // 虽然先启动 B 线程,但是并不能确定谁先谁后,具体要看谁先拿到 CPU 的调度权
        // 但是这里一定是 A 先执行,因为 B 线程加入了 A 线程,所以 A 会先执行
        threadB.start();
        threadA.start();
    }
}

class ThreadA extends Thread {
    @Override
    public void run() {
        System.out.println("A");
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class ThreadB extends Thread {
    private Thread t;
   
    @Override
    public void run() {
        try {
            // 把 t 线程加进来,等到 t 执行完毕后当前线程才会执行
            t.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("B");
    }
}

wait 和 notify/notifyAll

public class Main {
    public static void main(String[] args) {
        ChiPaoMian chiPaoMian = new ChiPaoMian();
        // 虽然这个线程先去启动但是因为 wait 了,所以不会真正执行(要等下面线程唤醒当前线程才会执行)
        new Thread(chiPaoMian::paoMian).start();
        // 这个线程启动后会直接执行,然后唤醒等待同一个锁的其他线程(就上面这个线程)
        new Thread(chiPaoMian::shaoKaiShui).start();
    }
}

// synchronized 方法锁当前对象,静态方法锁 class,保证两个方法使用的是同一把锁
class ChiPaoMian {
    
    public synchronized void shaoKaiShui(){
        System.out.println("烧开水...");
        notify();
    }
    
    public synchronized void paoMian(){
        try {
            wait();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("泡面...");
    }
}