为什么在 Java 的 Object 类中声明了 wait() 和 notify()?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1769489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are wait() and notify() declared in Java's Object class?
提问by Bhupi
Why are the wait()
and notify()
methods declared in the Object
class, rather than the Thread
class?
为什么wait()
和notify()
方法是在Object
类中声明的,而不是在Thread
类中声明的?
采纳答案by Andrzej Doyle
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 nota 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.
我认为您可能对这些方法的工作方式有误解。他们不是简单地在一个线程粒度级别,即它不只是通话的情况下wait()
,并通过下一呼叫被唤醒notify()
。相反,您总是调用wait()
特定对象,并且只会通过调用notify
该对象被唤醒。
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 anyconcurrent 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.
这很好,因为否则并发原语将无法扩展;这相当于拥有全局命名空间,因为notify()
对程序中任何地方的任何调用都有可能弄乱任何并发代码,因为它们会唤醒任何阻塞wait()
调用的线程。这就是您在特定对象上调用它们的原因;它为等待-通知对提供了一个操作上下文,因此当您myBlockingObject.notify()
在私有对象上调用, 时,您可以确保您只会唤醒在您的类中调用等待方法的线程。一些可能正在等待另一个对象的 Spring 线程不会被这个调用唤醒,反之亦然。
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 Threadto 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.
编辑:或者从另一个角度地址-我希望从你的问题,你以为你会得到一个处理的线程等待和呼叫notify()
在该线程将其唤醒。不这样做的原因是你必须自己做很多家务。将要等待的线程必须在其他线程可以看到的地方发布对自身的引用;这必须正确同步以强制执行一致性和可见性。当你想唤醒一个线程时,你必须抓住这个引用,唤醒它,然后从你读取它的任何地方删除它。与仅调用相比,涉及更多的手动脚手架,并且出错的可能性更大(尤其是在并发环境中)myObj.wait()
在休眠线程中,然后myObj.notify()
在唤醒线程中。
回答by Taylor Leese
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 javadocfor Object.notify()
and Object.wait()
it's described in detail.
因为一次只有一个线程可以拥有一个对象的监视器,而这个监视器是线程正在等待或通知的。如果你读了的javadoc为Object.notify()
和Object.wait()
它的详细描述。
回答by valli
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
最简单和明显的原因是任何对象(不仅仅是线程)都可以成为线程的监视器。在监视器上调用等待和通知。正在运行的线程检查监视器。所以 wait 和 notify 方法在 Object 而不是 Thread
回答by kgiannakakis
Read herefor an explanation of wait and notify.
阅读此处了解等待和通知的说明。
It would be better to avoid these however in your applications and use the newer java.util.concurrentpackage.
然而,最好在您的应用程序中避免这些并使用较新的java.util.concurrent包。
回答by Programmer in Paradise
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.
同步机制涉及一个概念——对象的监视器。当调用wait() 时,会请求监视器并暂停进一步的执行,直到获取监视器或发生InterruptedException。当notify() 被调用时,监视器被释放。
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.
让我们假设 wait() 和 notify() 放在 Thread 类而不是 Object 类中。在代码中的某一点currentThread.wait()
调用,然后anObject
访问一个对象。
//.........
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.
调用 currentThread.wait() 时,currentThread
会请求monitor of并且不会进一步执行,直到获取监视器或发生 InterruptedException。现在在等待状态下,如果从另一个线程调用驻留在其中foo()
的另一个对象的方法,即使被调用的方法没有访问,它也会卡住。如果调用第一个 wait() 方法,而不是线程本身,则驻留在同一线程中的对象上的其他方法调用(不访问)不会卡住。anotherObject
currentThread
foo()
anObject
anObject
anObject
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.
因此,在 Object 类(或其子类)上调用 wait() 和 notify() 方法提供了更大的并发性,这就是为什么这些方法在 Object 类中,而不是在 Thread 类中。
回答by Prabakaran Natarajan
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
要调用 wait() 或 notify() 您需要拥有对象监视器 - 这意味着 wait() 或 notify() 需要出现在同步块中
synchronized(monitorObj){
monitorObj.wait() or even notify
}
Thats the reason these methods are present in object class
这就是这些方法存在于对象类中的原因
回答by Sandeep
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.
这是因为,这些方法是用于线程间通信的,线程间通信是通过使用锁发生的,但是锁是与对象相关联的,因此它在对象类中。
回答by Anil Satija
Wait and Notify methods are used communication between two Threads in Java. So Object class is correct place to make them available for every object in Java.
在 Java 中,Wait 和 Notify 方法用于两个线程之间的通信。因此 Object 类是使它们可用于 Java 中的每个对象的正确位置。
Another reason is Locks are made available on per Object basis. Threads needs lock and they wait for lock, they don't know which threads holds lock instead they just know the lock is hold by some thread and they should wait for lock instead of knowing which thread is inside the synchronized block and asking them to release lock
另一个原因是锁是基于每个对象提供的。线程需要锁并等待锁,它们不知道哪个线程持有锁,而只知道锁被某个线程持有,它们应该等待锁而不是知道哪个线程在同步块内并要求它们释放锁
回答by Solomon Slow
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
“监视器”这个名字早在 1970 年代就被创造出来,它指的是一个对象,它有自己的内在锁和相关的等待/通知机制。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 objectwas a monitor.
20 年后,台式机、多处理器计算机出现了一个短暂的时刻,人们普遍认为为它们设计软件的正确方法是创建面向对象的程序,其中每个对象都是一个对象。监视器。
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.
事实证明,这并不是一个有用的想法,但那个短暂的时刻恰好是 Java 编程语言被发明的时候。