七、等待唤醒的三种方式
一、Object的wait、notify
注:
1、wait、notify必须绑定synchronized使用。
2、wait、notify有先后顺序,必须先等待后唤醒。
3、wait后,会释放锁。
public class TestDemo01 { static Object obj = new Object(); public static void main(String[] args) { syncWaitNotify(); } private static void syncWaitNotify() { new Thread(() -> { synchronized (obj) { System.out.println(Thread.currentThread().getName() + " come in"); try { obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 被唤醒"); } }, "A").start(); new Thread(() -> { synchronized (obj) { obj.notify(); System.out.println(Thread.currentThread().getName() + " 通知"); } }, "B").start(); } }
二、Condition的await、signal
注:
1、await、signal必须绑定lock使用。
2、await、signal有先后顺序,必须先等待后唤醒。
public class TestDemo01 {static Lock lock = new ReentrantLock(); static Condition condition = lock.newCondition(); public static void main(String[] args) { lockAwaitSignal(); } private static void lockAwaitSignal() { new Thread(() -> { lock.lock(); try { System.out.println(Thread.currentThread().getName() + " come in"); condition.await(); System.out.println(Thread.currentThread().getName() + " 被唤醒"); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }, "A").start(); new Thread(() -> { lock.lock(); try { condition.signal(); System.out.println(Thread.currentThread().getName() + " 通知"); } finally { lock.unlock(); } }, "B").start(); } }
三、LockSupport的park、unpark
LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞喝唤醒线程的功能,每个线程都有一个许可(permit),permit只有1和0两个值,默认0。
注:
1、park、unpark无需依赖锁。
2、park、unpark没有先后顺序,可以先通知,再唤醒。先upark()后,park()不会执行。
3、unpark()不可累计,无法唤醒线程中的多个park()。
4、LockSupport是调用Unsafe中的native代码。
public class LockSupportDemo {public static void main(String[] args) { lockSupport(); } private static void lockSupport() { Thread a = new Thread(() -> { System.out.println(Thread.currentThread().getName() + " come in"); LockSupport.park(); System.out.println(Thread.currentThread().getName() + " 被唤醒"); }, "a"); a.start(); // 暂停3s线程 try { TimeUnit.SECONDS.sleep(3L); } catch (InterruptedException e) { e.printStackTrace(); } Thread b = new Thread(() -> { LockSupport.unpark(a); System.out.println(Thread.currentThread().getName() + " 通知"); }, "b"); b.start(); } }