JUC---wait¬ify

JUC—wait¬ify

背景

  • JUC—wait¬ify

  • 博主以黑马JUC进行学习

    wait/notify原理

    Monitor:WaitSet EntryList Owner

    • Owner:当前持有锁的线程
    • Entry Set:等待获取锁的线程队列(BLOCKED
    • Wait Set:调用 wait() 后进入的等待队列(WAITING

    执行流程

    • Owner线程发现条件不满足,调用wait方法,即可进入WaitSet变为WAITING状态
    • BLOCKED和WAITING的线程都处于阻塞状态,不占用CPU时间片
    • BLOCKED线程会在Owner线程释放锁时唤醒
    • WAITING线程会在Owner线程调用notify或notifyAll时唤醒,但唤醒后并不意味着立刻获得锁,仍需要进入EntryList重新竞争

    API介绍

    • obj.wait()让进入object监视器的线程到waitSet等待
    • obj.wait(long n)有时限的等待,到n毫秒后结束等待,或是被notify
    • obj.notify()在object上正在waitSet等待的线程中挑一个唤醒
    • obj.notifyAll()让object上正在waitSet等待的线程全部唤醒
    方法 作用 关键特性
    wait() 当前线程释放锁,进入该对象的等待队列(Wait Set),暂停执行,直到被唤醒 必须在 synchronized 中调用;释放锁;进入 WAITING 状态
    wait(long timeout) 带超时的等待,超时未被唤醒则自动唤醒 超时后进入 BLOCKED 竞争锁
    notify() 随机唤醒等待队列中的一个线程,使其进入锁竞争队列(Entry Set) 唤醒后不立即执行,需等当前线程释放锁
    notifyAll() 唤醒等待队列中的所有线程,全部进入锁竞争队列 生产环境更推荐,避免死锁

    它们都是线程之间进行协作的手段,都属于Object对象的方法。必须获得此对象的锁,才能调用这几个方法

    • 进入了Owner,才有资格进入WaitSet

    wait VS sleep

    sleep(long n) 和 wait(long n) 的区别

    • sleep 是 Thread方法,而wait 是 Object 的方法
    • sleep 不需要强制和synchronized配合使用,但wait需要和synchronized一起用
    • sleep在睡眠的同时,不会释放对象锁的,但wait在等待的时候会释放对象锁
    • 它们状态 TIMED_WAITING
    特性 wait() sleep()
    所属类 Object Thread
    锁行为 释放锁 不释放锁
    使用场景 线程间协作、条件等待 线程暂停执行(延时)
    唤醒方式 notify()/notifyAll() 时间到自动唤醒
    调用前提 必须在 synchronized 任意位置