1.Synchronized + Object.wait() + Object.notify()/Object.notifyAll();
notify 是释放的是锁,不确定唤醒的是哪个线程;
1.锁的释放时机
-
notify()不会立即释放锁。调用notify()的线程会继续持有当前对象的锁,直到退出所属的synchronized同步代码块或方法后,才会释放锁。 - 被唤醒的线程(通过
notify())需要重新竞争该对象的锁,只有获得锁后才能继续执行。
2. 唤醒线程的选择
-
notify()会随机唤醒一个正在该对象上等待(通过wait())的线程。如果有多个线程处于等待状态,具体被唤醒的线程由线程调度器随机选择,而非按特定顺序。
补充说明
notifyAll()与notify()的区别在于:前者会唤醒所有等待线程,但这些线程仍需竞争锁。- 若需实现精准唤醒特定线程的逻辑,需通过条件变量或显式的锁管理机制(如
Lock和Condition接口)实现,而非依赖notify()的默认行为。
public class SynchronizedExample { public static void main(String[] args) { final Object lock = new Object(); Thread thread1 = new Thread(() -> { synchronized (lock) { System.out.println(Thread.currentThread().getName() + " come in"); try { lock.wait(); // 等待唤醒 System.out.println(Thread.currentThread().getName() + " 被唤醒"); } catch (InterruptedException e) { e.printStackTrace(); } } }, "thread01"); thread1.start(); try { TimeUnit.SECONDS.sleep(1); // 等待1秒以确保thread1先运行 } catch (InterruptedException e) { e.printStackTrace(); } Thread thread2 = new Thread(() -> { synchronized (lock) { System.out.println(Thread.currentThread().getName() + " 执行唤醒任务"); lock.notify(); // 唤醒等待的线程01 } }, "thread02"); thread2.start(); }
2.LockSupport.park()/LockSupport.unpark() 可以释放指定的线程上的锁
3.ReentrantLock + condition.await()/condition.signal()/condition.signalAll [底层是LockSupport.park()/LockSupport.unpark()]
浙公网安备 33010602011771号