wait() , notify() - which thread first unlock? - java

Trying to understand wait() and notify(). I know when thread A went to wait() it will be waked up by notify() from other thread.
But what will happens if threads A,B,C went to wait() in represented order? Who will be waked up by notify()? According to my experiments A thread will be waked up at first. I'm right?
Does it means that system knows in which order threads went to wait() ?

From the documentation for notify(), emphasis mine:
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
Some other APIs, such as Semaphore, have a concept of "fairness", where you can ensure that threads do proceed in the order in which they blocked.

Section 17.2.2 Notification of Java Language Specification:
There is no guarantee about which thread in the wait set is selected.
So, observed behavior is not guaranteed and should not be relied upon.

No, the VM does not know in which order the threads were put in Waiting state.
When you call notify(), one of them will be back to Alive/Runnable state and there is no way to know which one the VM will choose.
Sometimes they can run in the order they were put in Waiting state, but the specification does not guarantee that. So in a different VMs you can have a completely different results or even in the same VM, if you run the code multiple times.

No, there is no guarantee about the order. The javadoc of the notify method is pretty clear on this:
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.

There's no such an order. Either thread has an equal opportunity to get into runnable state. Actually JVM/OS can see them only as a set of waiting threads, they don't know any order.
In terms of your experiment, to get into a fair conclusion, actually you have to perform it for a huge number of times.
In threads, you can expect an order (FIFO), only if you are using something like a strong Semaphore. Then these threads are put into a waiting queue and fist comer would be first served.

Related

Difference between Locks and .join() method

Let's say you have two threads, thread1 and thread2. If you call thread1.start() and thread2.start() at the same time and they both print out numbers between 1 and 5, they will both run at the same time and they will randomly print out the numbers in any order, if I am not mistaken. To prevent this, you use the .join() method to make sure that a certain thread gets executed first. If this is what the .join() method does, what is the Lock object used for?
Thread.join is used to wait for another thread to finish. The join method uses the implicit lock on the Thread object and calls wait on it. When the thread being waited for finishes it notifies the waiting thread so it can stop waiting.
Java has different ways to use locks to protect access to data. There is implicit locking that uses a lock built into every Java object (this is where the synchronized keyword comes in), and then there are explicit Lock objects. Both of them protect data from concurrent access, the difference is the explicit Locks are more flexible and powerful, while implicit locking is designed to be easier to use.
With implicit locks, for instance, I can't not release the lock at the end of a synchronized method or block, the JVM makes sure that the lock gets released as the thread leaves. But programming with implicit locks can be limiting. For instance, there aren't separate condition objects so if there are different threads accessing a shared object for different things, notifying only a subset of them is not possible.
With explicit Locks you get separate condition objects and can notify only those threads waiting on a particular condition (producers might wait on one condition while consumers wait on another, see the ArrayBlockingQueue class for an example), and you can implement more involved kinds of patterns, like hand-over-hand locking. But you need to be much more careful, because the extra features introduce complications, and releasing the lock is up to you.
Locking typically prevents more than one thread from running a block of code at the same time. This is because only ONE thread at a time can acquire the lock and run the code within. If a thread wants the lock but it is already taken, then that thread goes into a wait state until the lock is released. If you have many threads waiting for the lock to be released, which one gets the lock next is INDETERMINATE (can't be predicted). This can lead to "thread starvation" where a thread is waiting for the lock, but it just never gets it because other threads always seem to get it instead. This is a very generic answer because you didn't specify a language. Some languages may differ slightly in that they might have a determinate method of deciding who gets the lock next.

How does wait() and notify() work in Java?

I am new to OS/multithreading and I'm wondering how wait() and notify() work together. I just saw this: Producer Consumer Solution in Java
And I'm kind of confused. Let's say I called wait() in PC.consume() method. When I reach the line that says notify() in PC.produce(), how does this wait in PC.consume() know that THAT is the one being notified? There could be other places that could be notified so how does it exactly know which to notify?
Thanks!
Wait and notify are called on the same object, the one being used as a lock (in the example that’s the object referenced by the local variable pc). The term used in the javadoc (here is the start of the api doc for the notify method) is “monitor”:
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
The OS has a thread scheduler that is making the arbitrary decision described in the javadoc, it decides things like when threads get context-switched or who gets notified.
So when a thread in consume waits, it goes dormant. Then eventually some other thread (in the example there are only two threads that acquire the lock on pc) calls notify on the same object the first thread called wait on, the scheduler picks the thread to be notified (has to be the first thread here because nothing else is waiting), and the notified thread wakes up and checks if there is anything to consume so it can know whether to proceed.

JAVA waking up threads in specific order

Let's say that i have 10 active threads and only 3 resources (of something)
while the first three threads got the resources i want all other thread that try to get the resource to wait but that the wake up or notify will be in f.i.f.o order i mean that the first thread that got the waiting will be the first to wake up.
thank you all.
I think this link explains it quite well: https://www.safaribooksonline.com/library/view/java-threads-second/1565924185/ch04s03.html
When using notify it is impossible to decide or determine in advance which thread will be allowed to execute. I see 2 solutions to this:
Use notifyAll() and let each thread check for itself whether whose turn it is (e.g. by using a synchronised FIFO queue)
Use the method described in the link: let each thread wait on a different object and use 1 thread that has as it's sole purpose to notify the correct object. This seems like the best solution to me.
Java generally doesn't decide these things however if you use a fair lock e.g.
Lock lock = new ReentrantLock(true);
then those threads will acquire the lock in the order they were attempted. This works by disregarding the order thread would be notified and ensuring a lock which is not taken unless the thread is next on the FIFO queue.

Are Java wait(), notify() 's implementation significantly different from locks?

Out of curiosity, when Java implements wait() and notify() methods, are they really just using locks? i.e., wait() acquires a mutex, notify() release a mutex, notifyAll() releases all mutexes (in the same object, of course)?
Other than being less cumbersome than using locks, are there other advantages of using wait() and notify()?
[EDIT] I realized what I confused myself about after Brian's comments:
wait doesn't lock, it releases the lock and passes it to someone else who's waiting on a synchronized statement for the mutex, then waits to be notified by someone else who has the lock and calls notify, which passes the lock back to the original thread that called wait. I think that's where you're getting confused. – Brian 17 mins ago
The other questions have focused on what the language says that wait and notify are - but that doesn't seem to be what your question is about... you talk about mutexes, which is an implementation detail and therefore JVM specific.
So we need to pick a JVM - let's pick openjdk (source available here). The bit of code that (ultimately) handles all this stuff is found at hotspot/src/share/vm/runtime/objectMonitor.cpp.
This maintains two datastructures - a wait set and an entry set. Waiting threads are added to the wait set and parked whereas threads attempting to take the monitor are added to the entry set and then parked. On notify a thread is taken from the wait set and added to the entry set. When a thread releases the lock it unparks a thread from the entry set if there is one. Note that these sets are actually implemented as queues (linked lists) so are treated on a FIFO basis.
Therefore, in this particular case the implementation treats waiting on an object's monitor and attempting to take an object's monitor in a similar way.
But this is just one implementation of one JVM (although it's likely that others do something similar) - so we cannot rely on it. So I suppose the question is why do you want to know? If it's just curiosity then look through the openjdk code, it's fascinating. If you plan on using this information in your code... don't.
UPDATE
I realise that saying "park" doesn't tell us much. The code that parks a thread is platform specific (and is implemented in an object called PlatformEvent, which ParkEvent extends). In the version of openjdk that I'm looking at the park code for linux can be found at hotspot/src/os/linux/vm/os_linux.cpp and this calls pthread_mutex_lock(_mutex)... so in answer to your question yes calling wait may take a mutex on my machine. Note that there's lots of stuff that happens above this which might prevent us getting to this point.
wait() and notify() don't do any monitor acquisition. as the javadoc for these methods state, the caller must have acquired the monitor before calling. in fact, wait() actually releases the monitor the caller acquired (although, i guess technically wait does do monitor (re)acquisition before finally returning).
wait releases the lock you already have with the intention of re-obtaining it at some point in the future after someone else calls notify. This is in addition to the locking mechanisms provided by synchronized. Basically, you use synchronized to obtain a lock, then you use wait, notify, and notifyAll to control how those locks are released and re-locked.
Out of curiosity, when Java implements wait() and notify() methods, are they really just using locks?
i.e., wait() acquires a mutex, notify() release a mutex, notifyAll() releases all mutexes?
Sorry, but none of that quite right. :)
It is the synchronized keyword that obtains the monitor. i.e. this is a form of locking. NB: using java.util.concurrent.locks.Lock does something similar.
wait() causes the current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed. Nothing to do with locking - but can only call this method when the current thread current thread already own's this object's monitor (in a synchronized block/method)
notify() wakes up a single thread that is waiting on this object's monitor. Again, nothing to do with locking - but can only call this method when the current thread current thread already own's this object's monitor (in a synchronized block/method)
wait(), notify() always work along with Synchronization , so comparison can be between Locks and synchronization. There is big difference between Locks like RentrantLock, ReadWriteLock and Synchronization [block, methods].
Locks dont use synchronization internally while wait(), notify() will need synchronization.
You use Lock along with java.util.concurrent.locks.Condition, which efficiently enables conditional locking, this is quite tedious to implement with synchronization..
You dont have any tryLock option with synchronization , you either take lock or wait. But with Lock interface you have the choice.

Does thread.yield() lose the lock on object if called inside a synchronized method?

I understand that Thread.currentThread().yield() is a notification to thread scheduler that it may assign cpu cycle to some other thread of same priority if any such is present.
My question is: If current thread has got lock on some object and calls yield(), will it loses that lock right away? And when thread scheduler finds out there is no such thread to assign cpu cycle, then the thread which has called yield() will again be in fight to get lock on the object which it has lost earlier??
I couldn't find it in javadoc and forums [http://www.coderanch.com/t/226223/java-programmer-SCJP/certification/does-sleep-yield-release-lock] have 50-50 answers.
I think yield() (lets say thread1) should release lock because if some thread (lets say thread2) of same priority wants to operate on same object, then it can have chance when thread scheduler eventually assign cup to thread2.
No. Thread.yield() is not like Object.wait(). It just gives up control to allow a thread switch. It will have no effect on the concurrency of your program.
There is no guarantee which thread the scheduler will run after a yield.
In Java Language specification
17.3 Sleep and Yield
It is important to note that neither Thread.sleep nor Thread.yield have any synchronization semantics. In particular, the compiler does not have to flush writes cached in registers out to shared memory before a call to Thread.sleep or Thread.yield, nor does the compiler have to reload values cached in registers after a call to Thread.sleep or Thread.yield.
My comment:
In java's early days, when it did not really supported parallel executions, but only concurrent (green threads), yield() was suspending the current thread, and the jvm was picking up another thread to resume. Now-days, yield does not have much meaning as usually the tread scheduling is on OS level.
So, yield is just a hint to the JVM that current thread wants to take a rest and nothing else, it is up to the thread scheduler to decide what to do. yield does not have any synchronization semantic. If thread holds lock, it will continue to hold it.
Only wait methods of the Object class release the intrinsic lock of the current instance (the thread may have other locks acquired, they don't get released). Yield, sleep, join do not bother about locks. However, join is a little more special, you are guaranteed to see all the changes made by the thread you're waiting for to finish.

Categories