知乎专栏 |
wait() 与 notify() 的用法
A 线程等待, 直到 B 线程发出通知
package cn.netkiller.test; public class Test { static Object object = new Object(); public static void main(String[] args) { Test test = new Test(); new Thread(() -> { synchronized (object) { System.out.println("开始线程 A"); try { object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("结束线程 A"); } }, "线程 A").start(); new Thread(() -> { try { Thread.sleep(500L); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (object) { System.out.println("开始线程 B"); object.notify(); System.out.println("结束线程 B"); } }, "线程 B").start(); } }
每次发送通知,只能通知到其中一个线程,多个线程必须多次发出通知。
package cn.netkiller.test; public class Test { static Object object = new Object(); public static void main(String[] args) { Test test = new Test(); new Thread(() -> { synchronized (object) { System.out.println("开始线程 A"); try { object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("结束线程 A"); } }, "线程 A").start(); new Thread(() -> { try { Thread.sleep(500L); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (object) { System.out.println("开始线程 B"); try { object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("结束线程 B"); } }, "线程 B").start(); new Thread(() -> { try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (object) { System.out.println("开始通知线程 C"); object.notify(); object.notify(); System.out.println("结束通知线程 C"); } }, "线程 C").start(); } }
notifyAll() 一次通知所有线程
new Thread(() -> { try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (object) { System.out.println("开始通知线程 C"); object.notifyAll(); System.out.println("结束通知线程 C"); } }, "线程 C").start();
package cn.netkiller.test; import lombok.Data; public class Test { private static final Message object = new Message(); public static void main(String[] args) { Test test = new Test(); new Thread(() -> { synchronized (object) { System.out.println("开始线程 A"); try { object.wait(); System.out.println(Thread.currentThread().getName() + ": " + object.getText()); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("结束线程 A"); } }, "线程 A").start(); new Thread(() -> { try { Thread.sleep(500L); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (object) { System.out.println("开始线程 B"); try { object.wait(); System.out.println(Thread.currentThread().getName() + ": " + object.getText()); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("结束线程 B"); } }, "线程 B").start(); new Thread(() -> { try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (object) { System.out.println("开始通知线程 C"); object.setText("https:/www.netkiller.cn"); object.notifyAll(); System.out.println("结束通知线程 C"); } }, "线程 C").start(); } @Data public static class Message { private String text; } }