多个线程协作工作场景很多,比如保证线程执行的先后顺序,生产者消费者等
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("泡面...");
}
}