public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();
}
}
}
In the example above, an object, b, is synchronized. b completes the calculation before Main thread outputs its total value.
output:
Waiting for b to complete...
Total is: 4950
If the main thread gains the lock of b first, then the main thread will execute the synchronized(b) block. Will b.wait() suspend thread b(thread b doesn't run yet)? If yes, how can this code produce the result?
If thread b gains the intrinsic lock first, what's the result of notify()?
When you use notify/wait you should do this based on a state change. if you do not, you open yourself to a number of issues.
If you notify() when there is no thread waiting, the notification is lost. A wait() coming later might wait forever.
If you wait(), it can wake spuriously i.e. it doesn't mean there was a notify.
The solution is to either;
not use notify/wait as it was largely replaced 10 years ago by the
concurrency libraries
have notify() thread change a field/state and have wait() thread
check this in a loop.
As James Large notes, wait()ing is not fair in the sense there is no guarantee the first thread to wait will be the next one notified.
Also you can't change state without holding the same synchronized lock and expect it to behave correctly all the time.
Will b.wait() suspend thread b(thread b doesn't run yet)? If yes, how
can this code produce the result?
No, it's the synchronized(this) (where this refers to the same object as b) that will block the other thread. Once b.wait is invoked, the monitor on the object referenced by b is released, the main thread goes to sleep, and the other thread acquires the monitor, entering the synchronized block.
If thread b gains the intrinsic lock first, what's the result of
notify()?
There are no threads waiting on b/this, so notify will basically do nothing. When your other thread releases the monitor, your main thread will acquire it and call wait, waiting forever since there's nothing else to notify it.
Related
This question already has an answer here:
Who notifies the Thread when it finishes?
(1 answer)
Closed 4 years ago.
Not sure why b.wait() doesn't wait the main thread. If we create a dummy object, Object a = new Object(); it waits. If I extend ThreadA with Thread and create a instance for ThreadA and lock using ThreadA reference it works. But why the below wait() doesn't work
package com.aircell;
public class ThreadA{
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
System.out.println("who is this thread");
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
}
System.out.println("done thread");
}
}
First of all: If I try out your class Here[TM] I get the following output:
who is this thread
Waiting for b to complete...
done thread
Total is: 4950
So it does work which is a bit surprising, but I think the following sentence in the Javadoc of wait seems to happen here:
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop.
The following change should give you the behavior you wanted to implement:
public class ThreadA{
public static void main(String[] args){
ThreadB b = new ThreadB();
System.out.println("who is this thread");
synchronized(b){
b.start();
try{
System.out.println("Waiting for b to complete...");
while (!b.finished) {
b.wait();
}
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread{
int total;
boolean finished;
#Override
public void run(){
synchronized(this){
try {
for(int i=0; i<100 ; i++){
total += i;
}
}
finally {
finished = true;
this.notifyAll();
}
}
System.out.println("done thread");
}
}
Wonderful question. Took me several hours to figure this out.
When a thread finishes execution, the thread object (in this case, object - "b") is notified by the JVM.
So, in the main thread, if the execution has reached b.wait() before ThreadB finishes, then an implicit b.notify() is called which notifies the main thread. The sequence that's happening in your code is either of the following 2 :
Case I :
b.start() is called.
However, before threadB can execute, main thread enters synchronized block, acquires lock, and calls b.wait().
b.wait() releases the lock, main thread is descheduled, and threadB begins execution.
threadB completes execution and lock is released.
Since threadB is completed, notify() is called on the Thread object. i.e., JVM triggers an implicit b.notify()
Main thread is awoken and completes it's task.
Case II :
b.start() is called.
threadB execution begins before main thread can acquire lock. Main thread is blocked on synchronized(b)
threadB completes execution and lock is released.
Main thread acquires lock and enters synchronization block and b.wait() is called.
Since threadB is completed, notify() is called on the Thread object. i.e., JVM triggers an implicit b.notify()
b.wait() releases the lock, main thread is descheduled, and 2nd thread begins execution.
Main thread is awoken and completes it's task.
However, if you add a delay in the main thread. Sufficient enough for ThreadB to finish before main thread can execute b.wait(), you will see that the main thread waits. If you put Thread.sleep(2000);
wait() method can not guarantee the execution to wait for first to finished but if you want one thread to fin
class ThreadA {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
synchronized (b) {
try {
System.out.println("Waiting for b to complete...");
b.wait();
} catch (InterruptedException e) {
}
System.out.println("Total is: " + b.total);
}
}}
class ThreadB extends Thread {
int total;
public void run() {
synchronized (this) {
for (int i = 0; i < 100; i++) {
total += i;
}
notify();
}
}}
I am unable to understand the code flow and how run method is being called in the above programs.
When the object is of class ThreadB then why main() thread of ThreadA is able to synchronize object b. Apart from that when wait() is encountered by the main() thread, how the executions shifts to run() in ThreadB.
Why does main() reaches to the synchronized block even before ThreadB's run() is able to execute.
Your program has a race condition.
After main() calls b.start() there are two threads running, unsynchronized, and they race to lock (i.e., synchronize on) the b object. There is no way to predict which thread will lock it first.
If the main() thread locks it first, then it will call b.wait(). That will temporarily unlock the b object, and allow the other thread to run. The other thread will do its work, call b.notify() and exit the synchronized block. As soon as it exits, the main() thread will be able to return from the wait() call.
If the second thread is first to lock the b object, the behavior will be different: It will do its work, call notify(), and return. But the notify() call will do nothing in that case because the main() thread will be blocked trying to enter the synchronized block. It won't be waiting in the b.wait() call, and notify() doesn't do anything if there isn't any other thread waiting.
So what will happen next in that case is, when the ThreadB thread leaves the synchronized block, the main() thread will be able to enter it and call wait(). The program will hang at that point because the ThreadB thread has already finished its work and died. There's no other thread left to call notify().
We call it a race condition when two (or more) threads race to do something, and the output of the program depends on which one gets there first.
Apart from that when wait() is encountered by the main() thread, how the executions shifts to run() in ThreadB.
Before invoke wait()
If it will invoke wait method next step, It means main thread hold monitor of object b currently. And if threadB want to execute run() method it will be blocked for waiting monitor of b which is hold by main thread.
invoke wait()
It means main thread release monitor, come into wait status, and advice thread scheduler re_dispatch. Then ThreadB can get monitor and make thing.
notify()
after finishing its job, threadB invoke notify() to wake up a single thread that is waiting on this object's monitor, here is main thread. And main thread will go on doing its work.
I'm looking at some notify/wait examples and came across this one. I understand a synchronized block essentially defines a critical section, but doesn't this present a race condition? Nothing specifies which synchronized block is entered first.
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();
}
}
}
Output per website:
Waiting for b to complete...
Total is: 4950
Right, it's not guaranteed which thread will execute first. The thread b could do its notification before the main thread ever starts to wait.
In addition to that, a thread can return from wait without having been notified, so setting a flag and checking it before entering the wait technically isn't good enough. You could rewrite it to something like
public class ThreadA {
public static void main(String[] args) throws InterruptedException {
ThreadB b = new ThreadB();
b.start();
synchronized(b){
while (!b.isDone()) {
System.out.println("Waiting for b to complete...");
b.wait();
}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
private boolean done = false;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
done = true;
notify();
}
}
public boolean isDone() {return done;}
}
so that the main thread will wait until b is done with its calculation, regardless who starts first.
By the way, the API documentation recommends you not synchronize on threads. The JDK synchronizes on threads to implement Thread#join. A thread that terminates sends a notifyAll that anything joining on it receives. If you were to call notify or notifyAll from a thread you've acquired the lock on, something joining on it could return early. One side effect of this here is that if you remove the notify the code works the same way.
Yes, it's a race condition. Nothing prevents ThreadB from starting, entering its run method, and synchronizing on itself prior to ThreadA from entering its synchronized block (thus waiting indefinitely). However, it's very unlikely to ever happen, considering the time it takes for a new thread to begin execution.
The easiest, and most recommended way to handle this type of situation is to not write your own implementation, but opt to use a callable/future provided by an Executor.
To fix this particular case without following standards:
Set a boolean 'finished' value set at the end of ThreadB's synchronized block.
If the boolean 'finished' is true after entering the synchronized block, then you should not call wait.
Yes - it is a race as to which thread enters which synchronized block first. For most scenarios of the race, the output and the answer will be the same. For one, however, the program will deadlock:
Main starts calls b.start() and immediately schedules out.
Thread B starts, enters synchronized, calls notify().
Main enters its synchronized block, calls wait()
In this case, main will wait forever since thread b called notify before main blocked on wait().
That said, this is unlikely - but with all threading you should conclude that it will happen and then at the worst possible time.
According to what I understood, when I use a synchronized block it acquires the lock on an object and releases it when the code block is done executing. In the following code
public class WaitAndNotify extends Thread{
long sum;
public static void main(String[] args) {
WaitAndNotify wan = new WaitAndNotify();
//wan.start();
synchronized(wan){
try {
wan.wait();
} catch (InterruptedException ex) {
Logger.getLogger(WaitAndNotify.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Sum is : " + wan.sum);
}
}
#Override
public void run(){
synchronized(this){
for(int i=0; i<1000000; i++){
sum = sum + i;
}
notify();
}
}
}
what happens if the synchronized block inside the run method acquires the lock first? Then the synchronized block inside the main method has to wait (not because of the wait(), because the other thread acquired the lock). After the run method is done executing, won't the main method enter its synchronized block and wait for a notify which it will never get? What did I misunderstand here?
wait() implicitly exits the respective monitor temporarily and re-enters it upon returning:
See wait()
The current thread must own this object's monitor. The thread releases
ownership of this monitor and waits until another thread notifies
threads waiting on this object's monitor to wake up either through a
call to the notify method or the notifyAll method. The thread then
waits until it can re-obtain ownership of the monitor and resumes
execution.
That's why and how this sort of synchronization does work at all.
Yes, it's possible to perform a notify() before a wait() causing a hung thread, so you need to be careful that it can't happen.
For that reason (and others) it's generally better to use the higher level constructs of java.util.concurrent, since they generally give you less possibilities to shoot yourself in the foot.
You won't see the 'waiting forever' issue here, because you are calling the version of wait() with a timeout; so, after 5 seconds it returns even if it doesn't receive a notify. The 'wait forever' version of the wait() call could indeed exhibit the problem you describe.
You've got two threads here: your WaitAndNotify (WAN) thread, and Java's main execution thread. Both are vying for the same lock.
If the WAN thread gets the lock first, the main thread will be blocked. Being in a blocked state is NOT the same as being in a wait state. A thread in the wait state will wait for notification before moving forward. A thread in the blocked state will actively try to get the lock when it becomes available (and keep trying until it does).
Assuming the run method executes normally, it will call notify(), which will have no effect because no other threads are currently in a wait state. Even if there were, WAN still holds the lock until it exits the synchronized block of code. Once WAN exits the block, THEN Java would notify a waiting thread (if there was one, which there is not).
At this point, the main execution thread now obtains the lock (it is no longer blocked) and enters the wait state. Now you've used the version of wait that will wait up to 5000 milliseconds before continuing. If you used the vanilla version (wait()) it would wait forever because no other process would notify it.
Here is a version of the example program changed to introduce a loop that tests a condition variable. This way you avoid bad assumptions about the state of things after a thread re-acquires a lock upon waking from a wait, and there's no order dependence between the two threads:
public class W extends Thread {
long sum;
boolean done;
public static void main(String[] args) throws InterruptedException {
W w = new W();
w.start();
synchronized(w) {
while (!w.done) {
w.wait();
}
// move to within synchronized block so sum
// updated value is required to be visible
System.out.println(w.sum);
}
}
#Override public synchronized void run() {
for (int i = 0; i < 1000000; i++) {
sum += i;
}
done = true;
// no notify required here, see nitpick at end
}
}
It's not sufficient to wait on a notification, for the reason you point out (order dependence, where you're relying on a race condition hoping one thread acquires the monitor before another) as well as for other reasons. For one thing, a thread can wake up from waiting without ever having received a notification, you can't assume that there was a notify call at all.
When a thread waits, it needs to do so in a loop, where in the test on the loop it checks some condition. The other thread should set that condition variable so the first thread can check it. The recommendation that the Oracle tutorial makes is:
Note: Always invoke wait inside a loop that tests for the condition being waited for. Don't assume that the interrupt was for the particular condition you were waiting for, or that the condition is still true.
Other nitpicks:
As your example is written, the JVM is not required to make the changes to your sum variable visible to the main thread. If you add a synchronized instance method to access the sum variable, or access the sum within a synchronized block, then the main thread will be guaranteed to see the updated value of sum.
Looking at your logging, there is nothing SEVERE about an InterruptedException, it doesn't mean anything went wrong. An InterruptedException is caused when you call interrupt on a thread, setting its interrupt flag, and that thread is either currently waiting or sleeping, or enters a wait or sleep method with the flag still set. In my toy example at the top of this answer I put the exception in the throws clause because I know it's not going to happen.
When the thread terminates it issues a notifyAll that anything waiting on that object will receive (again, that's how join is implemented). It's better style to use Runnable instead of Thread, partly because of this.
In this particular example it would make more sense to call Thread#join on the summing thread, rather than calling wait.
Here's the example re-written to use join instead:
public class J extends Thread {
private long sum;
synchronized long getSum() {return sum;}
public static void main(String[] args) throws InterruptedException {
J j = new J();
j.start();
j.join();
System.out.println(j.getSum());
}
#Override public synchronized void run() {
for (int i = 0; i < 1000000; i++) {
sum += i;
}
}
}
Thread#join calls wait, locking on the thread object. When the summing thread terminates it sends a notification and sets its isAlive flag to false. Meanwhile in the join method, the main thread is waiting on the summing thread object, it receives the notification, checks the isAlive flag, and realizes it doesn't have to wait anymore, so it can leave the join method and print the result.
Refer below code
public void acquire(){
synchronized(a){
print("acquire()");
try{
//Thread.sleep(5000);
synchronized(this){
wait(5000);
}
print("I have awoken");
print("" + a);
}catch(Exception e){
e.printStackTrace();
}
}
print("Leaving acquire()");
}
public void modify(int n){
print("Entered in modfy");
synchronized(a){
try{
//Thread.sleep(5000);
synchronized(this){
wait(5000);
}
this.a=n;
print("new value" + a);
}catch(Exception e){
e.printStackTrace();
}
}
}
And
final SynchoTest ttObj = new SynchoTest();
Thread A = new Thread(new Runnable(){
public void run() {
ttObj.acquire();
}
},"A");
Thread B = new Thread(new Runnable(){
public void run() {
ttObj.modify(97);
}
},"B");
A.start();
B.start();
As i know about wait(n), it pauses a thread until notify()/notifyAll() get called or the specified time n is over.
But...
In above methods if I directly use wait(n) as I used Thread.sleep(n),
I get runtime exception.
If I synchronize both methods instead of surrounding wait(n) with
synchronized block then I am not getting any exception but both
threads get blocked forever.
But if I do like I attached ie wait(n) surrounding with synchronized
block, it is working fine.
Please tell me why? Also tell me why is it not behaving different on positioning synchronized block if I use sleep(n) instead of wait(n)?
My question is about various result of wait(n) on various position of synchronized keyword.
#Gray
notify() or notifyAll(), and wait() must be in a synchronized block
for the object you are waiting on
explained me why I was getting run time exception by positioning synchronized block on various position.
Now please explain me, why
public void method(){
synchronized(a){
synchronized(this){
wait(n);
}
}
}
is working fine. But
public synchronized void method(){
synchronized(a){
wait(n);
}
}
is blocking my thread forever.
wait(n) and sleep(n) are completely different methods for pausing the execution of code:
wait(n) is called on an Object instance and will pause execution until the notify()/notifyAll() method is called on that instance or until the timer (the parameter) expires.
sleep(n) is called on a Thread object and essentially stops the world as far as that thread is concerned.
What your question comes down to is:
Do you want your object to act as a mutex, waiting for another piece of code to complete before continuing on it's own? Then use wait(n) with a corresponding notify()/notifyAll() in the other code.
Do you want to stop execution of the whole thread for a given timeframe? Then use Thread.sleep(n).
Maybe your code is not working because you didn't call start() on your threads? After you instantiate your threads you need to:
A.start();
B.start();
Also, you cannot do something like the following pattern. You cannot synchronize on a and then change the object of a. Well you can do it but I doubt that's what you want. Basically the a would change and someone else locking on a would lock on another object so would be able to be in the synchronized block as well. Very bad pattern.
synchronized (a) {
...
// not good
this.a = n;
}
Also, if you are not joining with the threads, then the main thread is going to continue on and not wait for A and B to finish. The JVM will wait for them to finish however since they are not daemon threads. And you have no guarantee that A will be called before B so the modify and acquire can happen in any order.
The difference between sleep(5000) and wait(5000) is that the wait can also be awoken by a call to notify() or notifyAll(), and wait() must be in a synchronized block for the object you are waiting on. synchronized also causes a memory barrier to be crossed which synchronizes the storage between multiple threads. It is more expensive because of that but in your case since you look to be sharing this.a then the memory barrier is required.
It is nothing about positioning synchronized keyword. You are facing problem since you locking other object and try to wait for another. Well #Gray has already been explained it, so not repeating it.
For your another problem, regarding why both threads are getting blocked;
Thread A: locks this [A: Runnable]
Thread A: locks a [A: Runnable]
Thread B: waiting for this [A: Runnable, B:BLOCKED]
Thread A: release this (meets wait) [A: TIMED WAITING, B:BLOCKED]
Thread B: lock this [A: TIMED WAITING, B: Runnable]
Thread B: waiting for a which is already locked by thread A [A: TIMED WAITING, B:BLOCKED]
Thread A: waiting for this which is locked by thread B [A: BLOCKED, B:BLOCKED]