跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Java 多线程问题
未分類
1 6 月 2020

Java 多线程问题

Java 多线程问题

資深大佬 : linxiaoziruo 1

为什么使用 notify 和 notifyAll 的时候要先获得锁?

大佬有話說 (13)

  • 資深大佬 : cs419

    没这个说法 不搭嘎

    你想想
    1. 为啥要用锁,不用锁会出啥问题 (原子性)
    2. 面对这个问题 怎么用 notify 去解决 (线程等待)

    如果确实要线程等待
    一般不用 notify 用 LockSupport

  • 主 資深大佬 : linxiaoziruo

    @cs419 怎么会不搭嘎呢,使用 notify 和 notifyAll 的时候必须要在 syncnorize 的临界区内,即必须先获得这个对象锁才能执行 notify,否则会抛出 IllegalMonitorStateException

  • 主 資深大佬 : linxiaoziruo

    @cs419 锁是解决共享资源竞争引起的线程安全问题,和原子性有什么关联呢,原子性指的是不能中断的操作,和锁是两个没有关联的概念。

  • 資深大佬 : 23571113

    notify 就是通知释放锁啊, 你没锁怎么释放.

  • 資深大佬 : pursuer

    notify,wait,和条件判断通常是一起用的,条件判断后选择进入等待或继续运行,这个时候要保证条件判断后,条件不会被其他线程改变,所以通常都会有个锁保障类似的场景。

  • 資深大佬 : sioncheng

    notify wait 是一种协作吧,双方需要能获得相同的锁才能说明是是在协作干一个事情,要不然,不相干的参与者瞎 notify 能行吗

  • 資深大佬 : lux182

    释放 monitor
    唤醒等待队列的线程

  • 資深大佬 : seki4713

    防止你条件判断成功后突然被抢占 然后条件被修改 保证判断条件到进入临界区的整个操作是原子的

  • 資深大佬 : bigbyto

    这个问题其实真不好回答,就像大家习以为常的问题,突然被问为什么了。其实上面的老哥都没回答到点上,我觉得为什么 notify 必须要 synchorized,根本原因在于 wait set 的操作是原子的。先看看 JLS 对 wait set 的描述。

    > Every object, in addition to having an associated monitor, has an associated *wait set*. A wait set is a set of threads.
    >
    > When an object is first created, its wait set is empty. **Elementary actions that add threads to and remove threads from wait sets are atomic**. Wait sets are manipulated solely through the methods `Object.wait`, `Object.notify`, and `Object.notifyAll`.
    >
    > Ref: https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html

    简单来说,当对象创建时,会顺带创建 Monitor 和 Wait Set,这些应该是在 C 语言层面去创建的。然后它告诉我们对 Wait Set 的操作都是 Atomic 的,这就能解释,为什么 wait 和 notify 必须获得锁,因为没有锁,就没办法保证对 wait set 的操作是原子的。

  • 資深大佬 : JasonLaw

    来自 Java Concurrency in Practice 。

    Just as each Java object can act as a lock, each object can also act as a condition queue, and the wait, notify, and notifyAll methods in Object constitute the API for intrinsic condition queues. An object’s intrinsic lock and its intrinsic condition queue are related: in order to call any of the condition queue methods on object X, you must hold the lock on X. This is because the mechanism for waiting for state-based conditions is necessarily tightly bound to the mechanism for preserving state consistency: you cannot wait for a condition unless you can examine the state, and you cannot release another thread from a condition wait unless you can modify the state.

    Object.wait atomically releases the lock and asks the OS to suspend the current thread, allowing other threads to acquire the lock and therefore modify the object state. Upon waking, it reacquires the lock before returning. Intuitively, calling wait means “I want to go to sleep, but wake me when something interesting happens”, and calling the notification methods means “something interesting happened”.

  • 資深大佬 : willxiang

    “必须在 synchronized 块中才能调用 wait()方法,因为 wait()方法调用时,会释放线程获得的锁,wait()方法返回后,线程又会重新试图获得锁。”

    https://www.liaoxuefeng.com/wiki/1252599548343744/1306580911915042

  • 資深大佬 : cs419

    忽然发现被降权了 没收到消息通知
    奇怪的知识增加了
    没觉着 wait 好用
    平时要么普通的多线程 要么 LockSupport 要么 JUC

  • 資深大佬 : Kamiyu0087

    直接从实际使用的情况来看的话,你如果 notify 的时候不去获得锁的话,没法保证 notify 在 wait 之后再执行啊
    “`java
    final Object lock = new Object();
    synchronized (lock) {
    new Thread(() -> lock.notify()).start();

    try {
    lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    “`

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具