This question already has answers here:
How can the wait() and notify() methods be called on Objects that are not threads?
(10 answers)
Closed 5 years ago.
I am just having hard time to understand concept behind putting wait() in Object class. For this questions sake consider if wait() and notifyAll() are in Thread class.
class Reader extends Thread {
Calculator c;
public Reader(Calculator calc) {
c = calc;
}
public void run() {
synchronized(c) { //line 9
try {
System.out.println("Waiting for calculation...");
c.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + c.total);
}
}
public static void main(String [] args) {
Calculator calculator = new Calculator();
new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
calculator.start();
}
}
class Calculator extends Thread {
int total;
public void run() {
synchronized(this) { //Line 31
for(int i=0;i<100;i++) {
total += i;
}
notifyAll();
}
}
}
My Question is that what difference it could have made? In line 9 we are acquiring lock on object c and then performing wait which satisfy the condition for wait that we need to acquire lock on the object before we use wait and so is case for notifyAll we have acquired lock on object of Calculator at line 31.
I am just having hard time to understand concept behind putting wait() in object class For this questions sake consider as if wait() and notifyAll() are in thread class
In the Java language, you wait() on a particular instance of an Object – a monitor assigned to that object to be precise. If you want to send a signal to one thread that is waiting on that specific object instance then you call notify() on that object. If you want to send a signal to all threads that are waiting on that object instance, you use notifyAll() on that object.
If wait() and notify() were on the Thread instead then each thread would have to know the status of every other thread. How would thread1 know that thread2 was waiting for access to a particular resource? If thread1 needed to call thread2.notify() it would have to somehow find out that thread2 was waiting. There would need to be some mechanism for threads to register the resources or actions that they need so others could signal them when stuff was ready or available.
In Java, the object itself is the entity that is shared between threads which allows them to communicate with each other. The threads have no specific knowledge of each other and they can run asynchronously. They run and they lock, wait, and notify on the object that they want to get access to. They have no knowledge of other threads and don't need to know their status. They don't need to know that it is thread2 which is waiting for the resource – they just notify on the resource and whomever it is that is waiting (if anyone) will be notified.
In Java, we then use objects as synchronization, mutex, and communication points between threads. We synchronize on an object to get mutex access to an important code block and to synchronize memory. We wait on an object if we are waiting for some condition to change – some resource to become available. We notify on an object if we want to awaken sleeping threads.
// locks should be final objects so the object instance we are synchronizing on,
// never changes
private final Object lock = new Object();
...
// ensure that the thread has a mutex lock on some key code
synchronized (lock) {
...
// i need to wait for other threads to finish with some resource
// this releases the lock and waits on the associated monitor
lock.wait();
...
// i need to signal another thread that some state has changed and they can
// awake and continue to run
lock.notify();
}
There can be any number of lock objects in your program – each locking a particular resource or code segment. You might have 100 lock objects and only 4 threads. As the threads run the various parts of the program, they get exclusive access to one of the lock objects. Again, they don't have to know the running status of the other threads.
This allows you to scale up or down the number of threads running in your software as much as you want. You find that the 4 threads is blocking too much on outside resources, then you can increase the number. Pushing your battered server too hard then reduce the number of running threads. The lock objects ensure mutex and communication between the threads independent of how many threads are running.
For better understanding why wait() and notify() method belongs to Object class, I'll give you a real life example:
Suppose a gas station has a single toilet, the key for which is kept at the service desk. The toilet is a shared resource for passing motorists. To use this shared resource the prospective user must acquire a key to the lock on the toilet. The user goes to the service desk and acquires the key, opens the door, locks it from the inside and uses the facilities.
Meanwhile, if a second prospective user arrives at the gas station he finds the toilet locked and therefore unavailable to him. He goes to the service desk but the key is not there because it is in the hands of the current user. When the current user finishes, he unlocks the door and returns the key to the service desk. He does not bother about waiting customers. The service desk gives the key to the waiting customer. If more than one prospective user turns up while the toilet is locked, they must form a queue waiting for the key to the lock. Each thread has no idea who is in the toilet.
Obviously in applying this analogy to Java, a Java thread is a user and the toilet is a block of code which the thread wishes to execute. Java provides a way to lock the code for a thread which is currently executing it using the synchronized keyword, and making other threads that wish to use it wait until the first thread is finished. These other threads are placed in the waiting state. Java is NOT AS FAIR as the service station because there is no queue for waiting threads. Any one of the waiting threads may get the monitor next, regardless of the order they asked for it. The only guarantee is that all threads will get to use the monitored code sooner or later.
Finally the answer to your question: the lock could be the key object or the service desk. None of which is a Thread.
However, these are the objects that currently decide whether the toilet is locked or open. These are the objects that are in a position to notify that the bathroom is open (“notify”) or ask people to wait when it is locked wait.
The other answers to this question all miss the key point that in Java, there is one mutex associated with every object. (I'm assuming you know what a mutex or "lock" is.) This is not the case in most programming languages which have the concept of "locks". For example, in Ruby, you have to explicitly create as many Mutex objects as you need.
I think I know why the creators of Java made this choice (although, in my opinion, it was a mistake). The reason has to do with the inclusion of the synchronized keyword. I believe that the creators of Java (naively) thought that by including synchronized methods in the language, it would become easy for people to write correct multithreaded code -- just encapsulate all your shared state in objects, declare the methods that access that state as synchronized, and you're done! But it didn't work out that way...
Anyways, since any class can have synchronized methods, there needs to be one mutex for each object, which the synchronized methods can lock and unlock.
wait and notify both rely on mutexes. Maybe you already understand why this is the case... if not I can add more explanation, but for now, let's just say that both methods need to work on a mutex. Each Java object has a mutex, so it makes sense that wait and notify can be called on any Java object. Which means that they need to be declared as methods of Object.
Another option would have been to put static methods on Thread or something, which would take any Object as an argument. That would have been much less confusing to new Java programmers. But they didn't do it that way. It's much too late to change any of these decisions; too bad!
In simple terms, the reasons are as follows.
Object has monitors.
Multiple threads can access one Object. Only one thread can hold object monitor at a time for synchronized methods/blocks.
wait(), notify() and notifyAll() method being in Object class allows all the threads created on that object to communicate with other
Locking ( using synchronized or Lock API) and Communication (wait() and notify()) are two different concepts.
If Thread class contains wait(), notify() and notifyAll() methods, then it will create below problems:
Thread communication problem
Synchronization on object won’t be possible. If each thread will have monitor, we won’t have any way of achieving synchronization
Inconsistency in state of object
Refer to this article for more details.
Answer to your first question is As every object in java has only one lock(monitor) andwait(),notify(),notifyAll() are used for monitor sharing thats why they are part of Object class rather than Threadclass.
wait and notify operations work on implicit lock, and implicit lock is something that make inter thread communication possible. And all objects have got their own copy of implicit object. so keeping wait and notify where implicit lock lives is a good decision.
Alternatively wait and notify could have lived in Thread class as well. than instead of wait() we may have to call Thread.getCurrentThread().wait(), same with notify.
For wait and notify operations there are two required parameters, one is thread who will be waiting or notifying other is implicit lock of the object . both are these could be available in Object as well as thread class as well. wait() method in Thread class would have done the same as it is doing in Object class, transition current thread to waiting state wait on the lock it had last acquired.
So yes i think wait and notify could have been there in Thread class as well but its more like a design decision to keep it in object class.
wait - wait method tells the current thread to give up monitor and go to sleep.
notify - Wakes up a single thread that is waiting on this object's monitor.
So you see wait() and notify() methods work at the monitor level, thread which is currently holding the monitor is asked to give up that monitor through wait() method and through notify method (or notifyAll) threads which are waiting on the object's monitor are notified that threads can wake up.
Important point to note here is that monitor is assigned to an object not to a particular thread. That's one reason why these methods are in Object class.
To reiterate threads wait on an Object's monitor (lock) and notify() is also called on an object to wake up a thread waiting on the Object's monitor.
These methods works on the locks and locks are associated with Object and not Threads. Hence, it is in Object class.
The methods wait(), notify() and notifyAll() are not only just methods, these are synchronization utility and used in communication mechanism among threads in Java.
For more detailed explanation, please visit : http://parameshk.blogspot.in/2013/11/why-wait-notify-and-notifyall-methods.html
This is just my 2 cents on this question...not sure if this holds true in its entirety.
Each Object has a monitor and waitset --> set of threads (this is probably more at OS level). This means the monitor and the waitset can be seen as private members of an object. Having wait() and notify() methods in Thread class would mean giving public access to the waitset or using get-set methods to modify the waitset. You wouldnt want to do that because thats bad designing.
Now given that the Object knows the thread/s waiting for its monitor, it should be the job of the Object to go and awaken those threads waiting for it rather than an Object of thread class going and awakening each one of them (which would be possible only if the thread class object is given access to the waitset). However, it is not the job of a particular thread to go and awaken each of the waiting threads. (This is exactly what would happened if all these methods were inside the Thread class). Its job is just to release the lock and move ahead with its own task. A thread works independently and does not need to know whihc other threads are waiting for the objects monitor (it is an unnecessary detail for the thread class object). If it started awakening each thread on its own.. it is moving from away its core functionality and that is to carry out its own task. When you think about a scene where there might 1000's of threads.. you can assume how much of a performance impact it can create. Hence, given that Object Class knows who is waiting on it, it can carry out the job awakening the waiting threads and the thread which sent notify() can carry out with its further processing.
To give an analogy (perhaps not the right one but cant think of anything else). When we have a power outage, we call a customer representative of that company because she knows the right people to contact to fix it. You as a consumer are not allowed to know who are the engineers behind it and even if you know, you cannot possibly call each one of them and tell them of your troubles (that is not ur duty. Your duty is to inform them about the outage and the CR's job is to go and notify(awaken) the right engineers for it).
Let me know if this sounds right... (I do have the ability to confuse sometimes with my words).
the wait() method will release the lock on the specified object and waits when it can retrieve the lock.
the notify(), notifyAll() will check if there are threads waiting to get the lock of an object and if possible will give it to them.
The reason why the locks are a part of the objects is because the resources (RAM) are defined by Object and not Thread.
The easiest method to understand this is that Threads can share Objects (in the example is calculator shared by all threads), but objects can not share Attributes ( like primitives, even references itself to Objects are not shared, they just point to the same location). So in orde to make sure only one thread will modify a object, the synchronized locking system is used
Wait and notify method always called on object so whether it may be Thread object or simple object (which does not extends Thread class)
Given Example will clear your all the doubts.
I have called wait and notify on class ObjB and that is the Thread class so we can say that wait and notify are called on any object.
public class ThreadA {
public static void main(String[] args){
ObjB b = new ObjB();
Threadc c = new Threadc(b);
ThreadD d = new ThreadD(b);
d.setPriority(5);
c.setPriority(1);
d.start();
c.start();
}
}
class ObjB {
int total;
int count(){
for(int i=0; i<100 ; i++){
total += i;
}
return total;
}}
class Threadc extends Thread{
ObjB b;
Threadc(ObjB objB){
b= objB;
}
int total;
#Override
public void run(){
System.out.print("Thread C run method");
synchronized(b){
total = b.count();
System.out.print("Thread C notified called ");
b.notify();
}
}
}
class ThreadD extends Thread{
ObjB b;
ThreadD(ObjB objB){
b= objB;
}
int total;
#Override
public void run(){
System.out.print("Thread D run method");
synchronized(b){
System.out.println("Waiting for b to complete...");
try {
b.wait();
System.out.print("Thread C B value is" + b.total);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Related
I am learning about cooperation between concurrent tasks and I have got that question and a possible answer to it. I would like to make sure I understand it correctly.
So to call a.wait() it is first required to synchronize on the object a or to be more precise a thread must become the owner of the a's monitor. As far as I understand, the only reason why a.wait() should be called in a synchronized context (together with a.notify()/a.notifyAll()) is to avoid a race condition/The Lost Wake-Up Problem. But theoretically, it is possible to avoid the race condition calling a.wait(),a.notify()/a.notifyAll() by synchronizing on some other object, like this:
Thread #1:
synchronized(b) {
…
a.wait(); // here a thread owns only one monitor: the monitor of the object stored in the variable b, where a != b
…
}
Thread #2:
synchronized(b) {
…
a.notify(); // the same here
…
}
The expected behavior is: the thread #1 acquires the monitor of b, enters the critical section, invokes a.wait(), then waits on a and releases the monitor of b. Afterwards the thread #2 acquires the monitor of b, enters the critical section, invokes a.notify() (the thread #1 gets notified), exits the critical section and releases the monitor of b, then the thread #1 acquires the monitor of b again and continues running. Thus, only one critical section synchronized on b can run at a time and no race condition can occur. You may ask, “but how would wait() know that the object b is used in this case to avoid the race condition and thus its monitor must be released?”. Well, that way it wouldn’t know. But maybe the wait method could take an object as an argument to know which object’s monitor to release, for example, a.wait(b), to wait on a and release the monitor of b. But there is no such an option: a.wait() causes a thread to wait on a and releases the monitor of exactly the same a. Period. The invocation of the wait and notify methods in the code above results in IllegalMonitorStateException.
According to this information from the Wikipedia article, the functionality of the wait, notify/notifyAll methods is built into every object's monitor where it is integrated into the functionality of the synchronization mechanism at the level of every individual object. But still it doesn't explain why it was done this way in the first place.
My answer to the question: before calling the wait method of an object, a thread should own the monitor of exactly the same object because to avoid a race condition this object is always not only a viable option but the best one.
Let’s see if there are any situations where it could be undesirable to synchronize on an object before invoking its wait, notify/notifyAll methods (plus some relevant logic). Synchronizing on the object would block it for other threads which could be undesirable if the object has some other synchronized methods (and/or there are some critical sections synchronized on the object) having nothing to do with the waiting logic. In that case it is always possible to refactor the corresponding class(es) so that the wait and notify/notifyAll methods operate on one object, while other synchronized methods/blocks operate on another one(s). For example, one of possible solutions could be creating a dedicated object specifically for a waiting logic (to wait and synchronize on) like in the example below:
public class A {
private Object lock = new Object(); // an object to synchronize and wait on for some waiting logic
private boolean isReady = false;
public void mOne() throws InterruptedException {
synchronized(lock) { // it blocks the instance of the Object class stored in the variable named lock
while(!isReady) {
lock.wait();
}
}
}
public void mTwo() {
synchronized(lock) { // the same here
isReady = true;
lock.notify();
}
}
synchronized public void mThree() { // it blocks an instance of A
// here is some logic having nothing to do with the above waiting and
// mThree() can run concurrently with mOne() and mTwo()
}
}
So there is no need to synchronize on some voluntary object to avoid a certain race condition regarding calling wait, notify/notifyAll methods. If it was allowed it would only cause unnecessary confusion.
Is it correct? Or maybe I am missing something here. I would like to make sure I don't miss anything important.
Oracle documentation: wait, notify, notifyAll
I have a method which is synchronized defined in some class.
We know that if we create a method as synchronized, then only one thread is able to execute the task at a time.
What is happening inside this method ?
How does other thread not able to execute the same task to run same method.
As per my knowledge, join is applied on that particular thread. But how does the second thread in the pipeline knows about the task has been done by first thread.
Tell me if i am right.
In the Java language, each Object has what is called a Monitor, which basically is a lock.
This lock is what powers Object methods such as wait / signal / signalAll that are available on every objects.
When using the synchronized keyword, what happens behind the scenes is that the compiler writes code that acquires the monitor (the lock) and releases it when invocation is complete.
If the method is static, the Monitor that is accessed is that of the Class object.
You can read more about this keyword here :
http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
One thread (first) acquires a lock on the object, and another thread waits for getting lock of that object.
Once task is done, first thread sends notification to waiting threads using notify() and notifyAll() methods.
We know that if we create a method as synchronized, then only one thread is able to execute the task at a time.
Not True! Two or more threads can enter the same synchronized block at the same time. And, that's not just in theory: It often happens in well-designed programs.
Here's what two or more threads can not do: Two or more threads can not synchronize on the same object at the same time. If you want to insure that only one thread at a time can enter a particular method (but why?†) then you need to write the method so that all calls to it will synchronize on the same object. That's easy to do if it's a static method because this:
class Foobar {
synchronized MyType baz() { ... }
}
means the same as this:
class Foobar {
MyType baz () {
synchronized (Foobar.class) { ... }
}
}
All calls to a static synchronized method synchronize on the class object that owns the method.
[what prevents two threads from synchronizing on the same object at the same time]?
The operating system. Any JVM that you would want to use for real work uses native threads to implement Java threads. A native thread is a thread that is created and managed by calls to the operating system. In particular, it's a part of the operating system known as the scheduler. I am not going to go into the details of how an operating system scheduler works---there's whole books written about that topic---but its job is to decide which threads get to run, when, and on what processor.
A typical scheduler uses queues to keep track of all of the threads that are not actually running. One special queue, the run queue, holds threads that are ready to run, but waiting for a CPU to run on. A thread on the run queue is called runnable. A thread on any other queue is blocked (i.e., not allowed to run) until something happens that causes the scheduler to put it back on the run queue.
The operating system object corresponding to a Java monitor (See #TheLostMind's answer) often is called a mutex or a lock. For each mutex, there is a queue of threads that are blocked, waiting to enter it. A native thread enters a mutex by calling the operating system. That gives the operating system the opportunity to pause the thread and add it to the mutex's queue if some other thread is already in the mutex. When a thread leaves a mutex, that's a system call too; and it gives the scheduler the opportunity to pick one thread off the mutex's queue, and put it back on the run queue.
Like I said, the details of how the scheduler does those things go way too deep to talk about here. Google is your friend.
† Don't worry about which threads can enter which method at the same time. Worry instead about which threads touch which data. The purpose of synchronization is to allow one thread to temporarily put your data into a state that you don't want other threads to see.
What is happening inside this method ?
When you say a (instance level) method is synchronized, A thread must first get a lock on the Object (i.e, first hold the monitor of that object) to access it. As long as one thread holds the lock / monitor, other threads cannot access it. because they cannot get a lock on the object (it is like door to the object).
How does other thread not able to execute the same task to run same method.
Because as long as one thread still holds the monitor, other threads wait. i.e, they cannot access the monitor themselves.So, they are blocked and will wait in the waiting set / queue for that object.
join is applied on that particular thread. But how does the second thread in the pipeline knows about the task has been done by first thread.
Join() ensures that the thread that calls join() on another thread, waits until the second thread completes its execution.
Note : A happens before relationship is established between the 2 threads when join is called. So that Whatever happens before a call to join or a return from join are always visible to other thread.
Edit :
Assume ThreadA and ThreadB are two threads running concurrently.
ThreadA
{
run(){
//some statements;
x=10; // assume x to be some shared variable
ThreadB.join();
// here ThreadA sees the value of "x" as 20. The same applies to synchronized blocks.
// Suppose ThreadA is executing in a Synchronized block of Object A, then after ThreadA //exits the synchronized block, then other threads will "always" see the changes made by //ThreadA
// some other statements
}
}
ThreadB{
run(){
//some statements
x=20;
}
check : Happens Before
How can the wait() and notify() methods be called on Objects that are not Threads? That doesn't really make sense, does it?
Surely, it must make sense, however, because the two methods are available for all Java objects. Can someone provide an explanation? I am having trouble understanding how to communicate between threads using wait() and notify().
Locking is about protecting shared data.
The lock is on the data structure being protected. The threads are the things accessing the data structure. The locks are on the data structure object in order to keep the threads from accessing the data structure in an unsafe way.
Any object can be used as an intrinsic lock (meaning used in conjunction with synchronized). This way you can guard access to any object by adding the synchronized modifier to the methods that access the shared data.
The wait and notify methods are called on objects that are being used as locks. The lock is a shared communication point:
When a thread that has a lock calls notifyAll on it, the other threads waiting on that same lock get notified. When a thread that has a lock calls notify on it, one of the threads waiting on that same lock gets notified.
When a thread that has a lock calls wait on it, the thread releases the lock and goes dormant until either a) it receives a notification, or b) it just wakes up arbitrarily (the "spurious wakeup"); the waiting thread remains stuck in the call to wait until it wakes up due to one of these 2 reasons, then the thread has to re-acquire the lock before it can exit the wait method.
See the Oracle tutorial on guarded blocks, the Drop class is the shared data structure, threads using the Producer and Consumer runnables are accessing it. Locking on the Drop object controls how the threads access the Drop object's data.
Threads get used as locks in the JVM implementation, application developers are advised to avoid using threads as locks. For instance, the documentation for Thread.join says:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Java 5 introduced explicit locks implementing java.util.concurrent.locks.Lock. These are more flexible than the implicit locks; there are methods analogous to wait and notify (await and signal), but they are on the Condition, not on the lock. Having multiple conditions makes it possible to target only those threads waiting for a particular type of notification.
You can use wait() and notify() to synchronize your logic. As an example
synchronized (lock) {
lock.wait(); // Will block until lock.notify() is called on another thread.
}
// Somewhere else...
...
synchronized (lock) {
lock.notify(); // Will wake up lock.wait()
}
with lock being the class member Object lock = new Object();
Think using a real life example, a washroom. When you want to use the washroom at your office, you have two options to make sure no one else will come to the washroom once you are using it.
Lock the washroom door, so everyone else will know that it's used by someone else when they try to open the door
Go to each person in the office, lock them to their chairs (or table, or whatever), go to washroom.
Which option would you take?
Yes, it's the same in the Javaland!.
So in the above story,
Washroom = Object you want to lock (that only you need to use)
Your staff colleagues = other threads that you want to keep out
So just like in real life, when you have some private business, you lock that object. And when you are done with that object, you let go of the lock!.
(Yes yes!, this is a very simple description on what happens. Of course the real concept is slightly different from this, but this is a starting point)
You can stop your thread for time as you want using static Thread class method sleep().
public class Main {
//some code here
//Thre thread will sleep for 5sec.
Thread.sleep(5000);
}
If you want to stop some objects you need to call this method's within syncronized blocks.
public class Main {
//some code
public void waitObject(Object object) throws InterruptedException {
synchronized(object) {
object.wait();
}
}
public void notifyObject(Object object) throws InterruptedException {
synchronized(object) {
object.notify();
}
}
}
P.S. I'm sory if I wrong understand your question (English is not my native)
When you put some code inside synchronized block:
sychronized(lock){...}
a thread wanting to perform whatever is inside this block first acquires a lock on an object and only one thread at a time can execute the code locked on the same object. Any object can be used as a lock but you should be careful to choose the object relevant to the scope. For example when you have multiple threads adding something to the account and they all have some code responsible for that inside a block like:
sychronized(this){...}
then no synchronization takes place because they all locked on different object. Instead you should use an account object as the lock.
Now consider that these threads have also method for withdrawing from an account. In this case a situation may occur where a thread wanting to withdraw something encounters an empty account. It should wait until there's some money and release the lock to other threads to avoid a deadlock. That's what wait and notify methods are for. In this example a thread that encounters an empty account releases the lock and waits for the signal from some thread that makes the deposit:
while(balance < amountToWithdraw){
lock.wait();
}
When other thread deposits some money, it signals other threads waiting on the same lock. (of course, code responsible for making deposits and withdrawals has to be synchronized on the same lock for this to work and to prevent data corruption).
balance += amountToDeposit;
lock.signallAll;
As you see the methods wait and notify only make sense inside synchronized blocks or methods.
In Java all Object implements these two methods, obviously if there are not a monitor those two methods are useless.
Actually, wait, notify member function should not belong to thread, the thing it should belong to name as condition variable which comes from posix thread . And you can have a look how cpp wrap this, it wrap it into a dedicated class std::condition_variable.
Java haven't do this kind encapsulation, instead, it wrap condition variable in more high level way: monitor (put the functionality into Object class directly).
If you don't know monitor or condition variable, well, that indeed make people confused at the beginning.
Wait and notify is not just normal methods or synchronization utility, more than that they are communication mechanism between two threads in Java. And Object class is correct place to make them available for every object if this mechanism is not available via any java keyword like synchronized. Remember synchronized and wait notify are two different area and don’t confuse that they are same or related. Synchronized is to provide mutual exclusion and ensuring thread safety of Java class like race condition while wait and notify are communication mechanism between two thread.
Locks are made available on per Object basis, which is another reason wait and notify is declared in Object class rather then Thread class.
In Java in order to enter critical section of code, 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. this analogy fits with wait and notify being on object class rather than thread in Java.
Analogy : a Java thread is a user and the toilet is a block of code which the thread wishes to execute. Java provides a way to lock the code for a thread which is currently executing it using the synchorinized keywokd, and making other threads that wish to use it wait until the first thread is finished. These other threads are placed in the waiting state. Java is NOT AS FAIR as the service station because there is no queue for waiting threads. Any one of the waiting threads may get the monitor next, regardless of the order they asked for it. The only guarantee is that all threads will get to use the monitored code sooner or later.
Source
If you look at the following producer and consumer code:
sharedQueue Object acts inter-thread communication between producer and consumer threads.
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ProducerConsumerSolution {
public static void main(String args[]) {
Vector<Integer> sharedQueue = new Vector<Integer>();
int size = 4;
Thread prodThread = new Thread(new Producer(sharedQueue, size), "Producer");
Thread consThread = new Thread(new Consumer(sharedQueue, size), "Consumer");
prodThread.start();
consThread.start();
}
}
class Producer implements Runnable {
private final Vector<Integer> sharedQueue;
private final int SIZE;
public Producer(Vector<Integer> sharedQueue, int size) {
this.sharedQueue = sharedQueue;
this.SIZE = size;
}
#Override
public void run() {
for (int i = 0; i < 7; i++) {
System.out.println("Produced: " + i);
try {
produce(i);
} catch (InterruptedException ex) {
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void produce(int i) throws InterruptedException {
// wait if queue is full
while (sharedQueue.size() == SIZE) {
synchronized (sharedQueue) {
System.out.println("Queue is full " + Thread.currentThread().getName() + " is waiting , size: "
+ sharedQueue.size());
sharedQueue.wait();
}
}
// producing element and notify consumers
synchronized (sharedQueue) {
sharedQueue.add(i);
sharedQueue.notifyAll();
}
}
}
class Consumer implements Runnable {
private final Vector<Integer> sharedQueue;
private final int SIZE;
public Consumer(Vector<Integer> sharedQueue, int size) {
this.sharedQueue = sharedQueue;
this.SIZE = size;
}
#Override
public void run() {
while (true) {
try {
System.out.println("Consumed: " + consume());
Thread.sleep(50);
} catch (InterruptedException ex) {
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private int consume() throws InterruptedException {
//wait if queue is empty
while (sharedQueue.isEmpty()) {
synchronized (sharedQueue) {
System.out.println("Queue is empty " + Thread.currentThread().getName()
+ " is waiting , size: " + sharedQueue.size());
sharedQueue.wait();
}
}
//Otherwise consume element and notify waiting producer
synchronized (sharedQueue) {
sharedQueue.notifyAll();
return (Integer) sharedQueue.remove(0);
}
}
}
Source
"This method should only be called by a thread that is the owner of this object's monitor."
So I think you must make sure there is a thread who is the monitor on the object.
Object class is the correct place to make a lock available for every object.
Suppose there is a joint bank account and hence multiple users can use the same account for transactions through multiple channels. Currently, the account has a balance of 1500/- and the minimum amount balance to remain in the account is 1000/-. Now, the first user is trying to withdraw an amount of 500/- through ATM and another user is trying to purchase any goods worth 500/- through a swipe machine. Here whichever channel first access the account to perform the transaction acquires the lock on the account at first and the other channel will wait until the transaction is completed and the lock on the account is released as there is no way to know which channel has already acquired the lock and which channel is waiting to acquire a lock. Hence lock is always applied on the account itself rather than a channel. Here, we can treat the account as an object and the channel as a thread.
i know that wait() method always written in synchronized method/block and make lock on Object but i want to only know that what problem is arise at that time when this all methods are in Thread class ?
They are also in the Thread class. But a thread instance here is equally well suited as a synchronization object as any other object.
In addition, there have already been voices that question this decision of sun, since now every object carries the burden to be able to be synchronized on, and IMHO they should have refactored this out to separate objects long ago.
If I need to have something to synchronize on, I often do:
private Object syncObject = new Object();
Then I can do my
synchronized(syncObject)
everywhere in the code and do not have to bother with anyone else accidentially synchronizing on this.
The problem with using them on a Thread object is that the Thread uses this lock for it own purposes. This is likely to lead to confusion and odd bugs.
These method's context is a lock associated with every object in Java so we can't move them to the Thread class. For example we might do something like this. Thread 1 adds an item to a list and notifies other threads about it. Thread 2 waits for a list update and does something with it:
thread 1
synchronized (lock) {
list.add(item);
lock.notifyAll();
}
thred 2
synchronized (lock) {
list.wait();
... do something with list
}
If these methods were moved to a thread, the thing we done here would be impossible.
These methods works on the locks and locks are associated with Object and not Threads. Hence, it is in Object class.
The methods wait(), notify() and notifyAll() are not only just methods, these are synchronization utility and used in communication mechanism among threads in Java.
For more explanation read: Why wait() ,notify() and notifyAll() methods are in Object class instead of Thread class?
Why are the wait() and notify() methods declared in the Object class, rather than the Thread class?
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.
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
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.
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.
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.
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.
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
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.
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.
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