outlookling

博客园 首页 新随笔 联系 订阅 管理

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()]

posted on 2025-05-14 13:22  jsonZhu  阅读(18)  评论(0)    收藏  举报