为什么在Java的Object类中声明wait()和notify()?

发布于 2024-08-12 02:49:23 字数 114 浏览 4 评论 0原文

为什么 wait()notify() 方法在 Object 类中声明,而不是在 Thread 类中声明?

Why are the wait() and notify() methods declared in the Object class, rather than the Thread class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

情徒 2024-08-19 02:49:23

因为,您等待给定的对象(或者具体来说,它的监视器)来使用此功能。

我认为您可能误解了这些方法的工作原理。它们不只是处于线程粒度级别,即不是仅调用wait()并被下一次调用唤醒的情况通知()。相反,您始终对特定对象调用 wait(),并且只能通过调用该对象上的 notify 来唤醒。

这很好,因为否则并发原语就无法扩展;它相当于拥有全局命名空间,因为在程序中任何地方对 notify() 的任何调用都有可能弄乱任何并发代码,因为它们会唤醒任何并发代码线程在 wait() 调用上阻塞。因此,您在特定对象上调用它们的原因;它为等待通知对提供了要操作的上下文,因此当您在私有对象上调用 myBlockingObject.notify() 时,您可以确保只会唤醒调用了类中的 wait 方法。某些可能正在等待另一个对象的 Spring 线程将不会被此调用唤醒,反之亦然。

编辑:或者从另一个角度解决它 - 我希望从你的问题中你认为你会得到等待线程的句柄并在该线程上调用 notify() 来唤醒起来吧。不这样做的原因是你必须自己做很多家务活。要等待的线程必须在其他线程可以看到的地方发布对自身的引用;这必须正确同步以增强一致性和可见性。当您想要唤醒一个线程时,您必须获取该引用,唤醒它,然后将其从您读取它的位置中删除。与仅在睡眠线程中调用 myObj.wait() 然后 相比,涉及更多的手动脚手架,并且出错的可能性更大(尤其是在并发环境中) myObj.notify() 在唤醒线程中。

Because, you wait on a given Object (or specifically, its monitor) to use this functionality.

I think you may be mistaken on how these methods work. They're not simply at a Thread-granularity level, i.e. it is not a case of just calling wait() and being woken up by the next call to notify(). Rather, you always call wait() on a specific object, and will only be woken by calls to notify on that object.

This is good because otherwise concurrency primitives just wouldn't scale; it would be equivalent to having global namespaces, since any calls to notify() anywhere in your program would have the potential to mess up any concurrent code as they would wake up any threads blocking on a wait() call. Hence the reason that you call them on a specific object; it gives a context for the wait-notify pair to operate on, so when you call myBlockingObject.notify(), on a private object, you can be sure that you'll only wake up threads that called wait methods in your class. Some Spring thread that might be waiting on another object will not be woken up by this call, and vice versa.

Edit: Or to address it from another perspective - I expect from your question you thought you would get a handle to the waiting thread and call notify() on that Thread to wake it up. The reason it's not done this way, is that you would have to do a lot of housekeeping yourself. The thread going to wait would have to publish a reference to itself somewhere that other threads could see it; this would have to be properly synchronized to enforce consistency and visibility. And when you want to wake up a thread you'd have to get hold of this reference, awaken it, and remove it from wherever you read it from. There's a lot more manual scaffolding involved, and a lot more chance of going wrong with it (especially in a concurrent environment) compared to just calling myObj.wait() in the sleeping thread and then myObj.notify() in the waker thread.

来日方长 2024-08-19 02:49:23

最简单和明显的原因是任何对象(不仅仅是线程)
可以是线程的监视器。等待和通知被调用
监视器。正在运行的线程与监视器进行检查。所以wait和notify方法是在Object中而不是Thread中

The most simple and obvious reason is that any Object (not just a thread)
can be the monitor for a thread. The wait and notify are called on the
monitor. The running thread checks with the monitor. So the wait and notify methods are in Object and not Thread

只是在用心讲痛 2024-08-19 02:49:23

因为一次只有一个线程可以拥有对象的监视器,而该监视器是线程正在等待或通知的对象。如果您阅读 javadoc 的 < code>Object.notify() 和 Object.wait() 对此进行了详细描述。

Because only one thread at a time can own an object's monitor and this monitor is what the threads are waiting on or notifying. If you read the javadoc for Object.notify() and Object.wait() it's described in detail.

笑忘罢 2024-08-19 02:49:23

同步的机制涉及到一个概念——对象的监视器。当调用 wait() 时,会请求监视器并暂停进一步的执行,直到获取监视器或发生 InterruptedException。当notify()被调用时,监视器被释放。

让我们假设一个场景,如果 wait() 和 notification() 被放置在 Thread 类而不是 Object 类中。在代码中的某一时刻,调用currentThread.wait(),然后访问一个对象anObject

//.........
currentThread.wait();
anObject.setValue(1);
//.........

当调用 currentThread.wait() 时,会请求 currentThread 的监视器,并且在获取监视器或发生 InterruptedException 之前不会进一步执行。现在,在等待状态下,如果从另一个线程调用驻留在 currentThread 中的另一个对象 anotherObject 的方法 foo(),它甚至会被卡住尽管被调用的方法 foo() 不会访问 anObject。如果第一个 wait() 方法是在 anObject 上调用的,而不是在线程本身上调用的,则驻留在同一线程中的对象上的其他方法调用(不访问 anObject)将不会得到卡住。

因此,在 Object 类(或其子类)上调用 wait() 和 notification() 方法可以提供更大的并发性,这就是为什么这些方法位于 Object 类中,而不是位于 Thread 类中。

The mechanism of synchronization involves a concept - monitor of an object. When wait() is called, the monitor is requested and further execution is suspended until monitor is acquired or InterruptedException occurs. When notify() is called, the monitor is released.

Let's take a scenario if wait() and notify() were placed in Thread class instead of Object class. At one point in the code, currentThread.wait() is called and then an object anObject is accessed.

//.........
currentThread.wait();
anObject.setValue(1);
//.........

When currentThread.wait() is called, monitor of currentThread is requested and no further execution is made until either the monitor is acquired or InterruptedException occurs. Now while in waiting state, if a method foo() of another object anotherObject residing in currentThread is called from another thread, it is stuck even though the called method foo() does not access anObject. If the first wait() method was called on anObject, instead of the thread itself, other method calls (not accessing anObject) on objects residing in the same thread would not get stuck.

Thus calling wait() and notify() methods on Object class(or its subclasses) provides greater concurrency and that's why these methods are in Object class, not in Thread class.

菩提树下叶撕阳。 2024-08-19 02:49:23

其他一些答案使用“监视器”一词,但没有解释它的含义。

“监视器”这个名字早在 20 世纪 70 年代就被创造出来了,它指的是一个拥有自己的内在锁和关联的等待/通知机制的对象。 https://en.wikipedia.org/wiki/Monitor_%28synchronization%29

二十年后,有一个短暂的时刻,台式多处理器计算机成为了新事物,人们认为为它们设计软件的正确方法是创建面向对象的程序,其中每个对象是一个监视器。

事实证明这并不是一个有用的想法,但那个短暂的时刻恰好是 Java 编程语言被发明的时候。

A few of the other answers use the word "monitor", but none explain what it means.

The name "monitor" was coined way back in the 1970s, and it referred to an object that had its own intrinsic lock, and associated wait/notify mechanism. https://en.wikipedia.org/wiki/Monitor_%28synchronization%29

Twenty years later, there was a brief moment in time when desktop, multi-processor computers were new, and it was fashionable to think that the right way to design software for them would be to create object-oriented programs in which every object was a monitor.

Turns out not to have been such a useful idea, but that brief moment happens to be exactly when the Java programming language was invented.

看海 2024-08-19 02:49:23

请阅读此处了解 wait 和通知。

然而,最好在您的应用程序中避免这些,并使用较新的 java.util.concurrent 包。

Read here for an explanation of wait and notify.

It would be better to avoid these however in your applications and use the newer java.util.concurrent package.

静谧幽蓝 2024-08-19 02:49:23

我会用一种简单的方式来表达:

要调用 wait() 或 notification(),您需要拥有对象监视器 - 这意味着 wait() 或 notify() 需要出现在同步块中,

synchronized(monitorObj){
monitorObj.wait()  or even notify
}

这就是这些方法存在的原因在对象类中

I will put it in a simple way:

To call wait() or notify() you need to own the object monitor - this means wait() or notify() needs to be present in the synchronized block

synchronized(monitorObj){
monitorObj.wait()  or even notify
}

Thats the reason these methods are present in object class

陌伤ぢ 2024-08-19 02:49:23

这是因为,这些方法用于线程间通信,而线程间通信是通过使用锁进行的,但锁与对象相关联。因此它位于对象类中。

This is because,these methods are for inter thread communication and interthreadcommunication happens by using locks, but locks are associated with objects.hence it is in object class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文