Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是Java wait()、notify()和#x27;s的实现与锁有显著不同?_Java_Multithreading_Concurrency_Locking_Wait - Fatal编程技术网

是Java wait()、notify()和#x27;s的实现与锁有显著不同?

是Java wait()、notify()和#x27;s的实现与锁有显著不同?,java,multithreading,concurrency,locking,wait,Java,Multithreading,Concurrency,Locking,Wait,出于好奇,当Java实现wait()和notify()方法时,它们真的只是使用锁吗?i、 例如,wait()获取一个互斥体,notify()释放一个互斥体,notifyAll()释放所有互斥体(当然是在同一个对象中) 使用wait()和notify()除了没有使用锁那么麻烦之外,还有其他好处吗 [编辑]在布赖恩的评论之后,我意识到我自己的困惑: wait不锁定,它释放锁并将其传递给正在等待mutex的synchronized语句的其他人,然后等待拥有锁的其他人通知并调用notify,这会将锁传递

出于好奇,当Java实现wait()和notify()方法时,它们真的只是使用锁吗?i、 例如,wait()获取一个互斥体,notify()释放一个互斥体,notifyAll()释放所有互斥体(当然是在同一个对象中)

使用wait()和notify()除了没有使用锁那么麻烦之外,还有其他好处吗

[编辑]在布赖恩的评论之后,我意识到我自己的困惑:


wait不锁定,它释放锁并将其传递给正在等待mutex的synchronized语句的其他人,然后等待拥有锁的其他人通知并调用notify,这会将锁传递回调用wait的原始线程。我想这就是你感到困惑的地方Brian 17分钟前

wait()
notify()
不要进行任何监视器采集。正如这些方法的javadoc所述,调用方必须在调用之前获取监视器。事实上,
wait()
实际上会释放调用者获取的监视器(虽然我猜从技术上讲wait确实会在最终返回之前监视(重新)获取)。

wait
释放你已经拥有的锁,目的是在将来其他人调用
notify
后的某个时候重新获取它。这是对
synchronized
提供的锁定机制的补充。基本上,您可以使用
synchronized
来获取锁,然后使用
wait
notify
notifyAll
来控制这些锁的释放和重新锁定方式。

wait()
notify()
始终与同步一起工作,因此可以在锁和同步之间进行比较。像RentrantLock、ReadWriteLock和Synchronization[block,methods]这样的锁之间有很大的区别

  • 锁在内部不使用同步,而
    wait()
    notify()
    将需要同步

  • 您可以将Lock与java.util.concurrent.locks.Condition一起使用,这可以有效地启用条件锁定,但使用同步实现这一点非常繁琐

  • 您没有任何tryLock选项与同步,您要么采取锁定或等待。但是使用锁接口,您可以选择

  • 出于好奇,当Java实现wait()和notify()方法时,它们真的只是使用锁吗? i、 例如,wait()获取一个互斥体,notify()释放一个互斥体,notifyAll()释放所有互斥体

    对不起,这些都不对

    • 正是
      synchronized
      关键字获得了
      监视器
      。i、 这是一种锁定形式。注意:使用
      java.util.concurrent.locks.Lock
      可以做类似的事情
    • wait()
      使当前线程等待,直到另一个线程调用此对象的
      notify()
      方法或
      notifyAll()
      方法,或者经过指定的时间。与锁定无关-但只能在当前线程当前线程已经拥有此对象的监视器时调用此方法(在
      synchronized
      block/method中)
    • notify()
      唤醒等待此对象监视器的单个线程。同样,与锁定无关-但只能在当前线程当前线程已经拥有此对象的监视器时调用此方法(在
      synchronized
      block/method中)

    其他问题集中在语言所说的
    等待
    通知
    是什么-但这似乎不是你的问题的重点。。。您将讨论互斥体,这是一个实现细节,因此是特定于JVM的

    所以我们需要选择一个JVM——让我们选择openjdk(源代码可用)。(最终)处理所有这些内容的代码位于
    热点/src/share/vm/runtime/objectMonitor.cpp

    这维护了两个数据结构—等待集和条目集。等待线程被添加到等待集中并停止,而试图获取监视器的线程被添加到条目集中并停止。在
    notify
    上,从等待集获取一个线程并将其添加到条目集。当一个线程释放锁时,如果有一个线程,它将从条目集中解压该线程。请注意,这些集合实际上是作为队列(链表)实现的,因此在FIFO的基础上进行处理

    因此,在这种特殊情况下,实现将以类似的方式处理等待对象的监视器和尝试获取对象的监视器

    但这只是一个JVM的一个实现(尽管其他JVM也可能做类似的事情),所以我们不能依赖它。所以我想问题是你为什么想知道?如果只是好奇的话,那么看看openjdk代码,它很吸引人。如果您计划在代码中使用此信息。。。不要

    更新


    我意识到说“公园”并不能告诉我们太多。驻留线程的代码是特定于平台的(并在名为
    PlatformEvent
    的对象中实现,该对象扩展了
    ParkEvent
    )。在我正在查看的openjdk版本中,linux的park代码可以在
    hotspot/src/os/linux/vm/os_linux.cpp中找到,这将调用
    pthread\u mutex\u lock(_mutex)
    。。。因此,在回答您的问题时,呼叫等待可能会占用我机器上的互斥锁。请注意,上面发生的许多事情可能会阻止我们达到这一点。

    notifyAll()释放同一对象上的所有等待。一点也不一样。@EJP当然,我的意思是所有对象都在同一个对象上等待,类似于释放这个对象在wait()中获得的所有互斥体,如果它们的隐式实现是相同的。等待和互斥体怎么会是相同的呢?假设有多个互斥体,w