Trying to understand synchronized methods - java

For the code below, the expected output is:
Waiting for b to complete...
Total is: 4950
How come it can't print the Total is.. first then Waiting for b.. after? I'd think b.start() could be executed first in some cases, then it holds onto ThreadB's lock with synchronized(this) in ThreadB.run() thus blocking main from entering in synchronized(b).
Is anything wrong with what I just stated?
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();
}
}
}

The two output statements will always have the same order, because they are executed on one thread. Waiting for another thread to finish between them will not change their execution order.
If you put the "Total is ..." output to the end of b's run() then there might be a chance for seeing indeterministic orders of the outputs.
EDIT - Please also note #Holger 's comment to this answer:
[...] in the unlikely, but still possible case that ThreadB’s synchronized block is executed first, its notify() call will have no effect as no-one is waiting yet and then, ThreadA’s wait() call may hang forever as there will be no subsequent notification.

Actual problem over here is you have only one thread "b" over here and you are calling wait() on b which is taking b thread to WAIT state and there is no other thread which can notify this thread and bring b back to runnign state.

Related

Thread Synchronization in java

Why I'm not able to achieve Synchronization on this below piece of program:
class P
{
synchronized void pp(String s)
{
System.out.println (s);
}
}
class threadA extends Thread
{
P ob;
String s;
threadA (P ob, String s)
{
this.ob = ob;
this.s = s;
}
public void run ()
{
for (int i=1;i<=5;++i)
{
ob.pp (s);
try
{
Thread.sleep (1000);
}
catch (Exception e) {}
}
}
}
class gain
{
public static void main(String[] args) {
P ob = new P ();
threadA a = new threadA (ob,"Hello User");
threadA b = new threadA (ob,"Bye User");
a.start();
b.start();
}
}
OP:
Hello User
Bye User
Hello User
Bye User
Bye User
...
I want OP in the form of:
Hello User
Hello User
Hello User..
Bye User
Bye User
Bye User..
or my concept of synchronization is wrong?
You cannot do such synchronization from P class. What happens now is that any calls to pp() is blocked if another thread is currently executing the method. As long as the method ends (which is quick if you are just going to print things to the console), the next thread would be allowed to enter the method.
What you are trying to achieve is not possible, unless both the threads are aware of each other and communicate with each other. In other words, when the first thread finishes what it needs to do, it should explicitly inform the second thread to start. This is effectively executing sequentially, instead of parallelly.
Update
You wanted to visualize what is happening so I'll do it here.
You created 2 threads.
You start the first thread.
The first thread starts to run, while some time later the second starts to run as well.
When your first thread runs, it goes to the for loop. Then it calls P.pp().
When P.pp() is called from first thread, it locks the P object.
Since the method is so short, it is going to exit very quickly.
When the method exits, it releases the lock on P.
If your second thread reaches the synchronize block before the first thread exits, it will wait (blocked).
When the first thread exits, the second thread enters as the first thread releases the lock.
The first thread returns to the loop and try to call P.pp() again.
This will continue, depending on which thread is faster, the order of execution would be different.
Synchronized keyword means that two threads on that code block have to respect the order they tried to access that block code. It doesn't mean that the execution flow is serialized.
To have what you want try to put the for inside the synchronized block...
You should try something like this
class P
{
void pp(String s)
{
System.out.println (s);
}
}
class threadA extends Thread
{
P ob;
String s;
threadA (P ob, String s)
{
this.ob = ob;
this.s = s;
}
public void run ()
{
for (int i=1;i<=5;++i)
{
synchronized(ob)
{
ob.pp (s);
try
{
Thread.sleep (10);
}
catch (Exception e) {}
}
}
}
}
public class gain
{
public static void main(String[] args) {
P ob = new P ();
threadA a = new threadA (ob,"Hello User");
threadA b = new threadA (ob,"Bye User");
a.start();
b.start();
}
}
i.e while sleeping keep thread synchronized so that you get required output or else you are not sure which thread might come up first after sleep. See this
can u explain me the flow of control of my program?
"Hello" starts and run through the loop until it reaches the synchronized method
"Bye" does the same.
"Hello" is the first to acquire the lock.
"Bye" blocks waiting for the lock.
"Hello" executes the method and releases the lock.
"Bye" can now acquire the lock and "Hello" has released it
"Bye" can now execute the method, and releases the lock as "Hello" did.
what can I do so that hello after executing the method goes to blocked pool and also doesn't leaves the lock for bye to acquire it
Hold the lock, and don't release it if you want to retain it.
public void run() {
synchronized(ob); { // hold the lock the whole time
for (int i = 1; i <= 5; ++i) {
ob.pp (s);
try { Thread.sleep(1000); } catch (Exception e) {}
}
} // releases the lock here.
}

Why b.wait() doesn't make the main thread wait [duplicate]

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

Is there a race condition in this example? If so, how could it be avoided?

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.

Program gets halted: wait() and notify()

I am trying to achieve this: Created two different threads, one prints odd numbers, one prints even numbers. Once one thread prints a number, it has to wait for the other thread and so on, that is one-after-other.
To achieve this, i am using synchronized block along with wait() and notify().
I am creating a class whose's object will be used to pass to synchronized block in both the threads.
Here is the code:
--> This is used object which will be passed to synchronized block.
package com.vipin.multithread.variousdemos;
public class SyncObject {
public SyncObject () {
}
}
Odd Thread:
package com.vipin.multithread.variousdemos;
public class OddThread implements Runnable {
private Thread t;
int index=0;
SyncObject so=null;
int odd_nums[] = {1,3,5,7,9};
public OddThread(SyncObject so) {
t = new Thread(this,"Odd Thread");
this.so = so;
t.start();
}
public Thread getThreadInstance() {
return t;
}
#Override
public void run() {
while (true) {
synchronized(so) {
System.out.println("Odd num is --->" + odd_nums[index]);
try {
so.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
index++;
so.notify();
if(index>=5) {
return;
}
}
}
}
}
Even Thread: UPDATE
package com.vipin.multithread.variousdemos;
public class EvenThread implements Runnable {
private Thread t;
int index=0;
SyncObject so=null;
int even_nums[] = {2,4,6,8,10};
public EvenThread(SyncObject so) {
t = new Thread(this, "Even thread");
this.so = so;
t.start();
}
public Thread getThreadInstance() {
return t;
}
#Override
public void run() {
while(true) {
synchronized(so) {
System.out.println("Even num is --->" + even_nums[index]);
so.notify(); <-- Here we are notifying.
try {
so.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
index++;
//so.notify(); <-- commented out.
if(index>=5) {
break;
}
}
}
}
}
Main Application:
package com.vipin.multithread.variousdemos;
public class EvenOddDemo {
public static void main(String[] args) throws InterruptedException {
SyncObject so = new SyncObject();
OddThread ot = new OddThread(so);
EvenThread et = new EvenThread(so);
System.out.println("\nIn main thread");
Thread.sleep(1000000000);
System.out.println("Exiting main thread...");
}
}
---> As seen in the code, I am creating two threads to print even and odd numbers. I am using synchronized block, and passing object of type ==> SyncObject.
SyncObject I am passing as argument to these different threads in main.
However, this programs halts, i.e stuck only first statement gets executed, and then it waits forever:
Here is the output:
Odd num is --->1
In main thread
Even num is --->2
I am not able to understand why this program waits for ever, I am using SAME object on which we are invoking synchronized(), wait() and notify(). As per my understanding, it should work, not sure why this is not working.
Any clues as to why this is waiting forever.
UPDATE:
I did some changes in the code, UPDATE and it works fine.
I still have some doubt. Does notify() be called by the thread even if it has not locked the monitor, like in my case after i updated the code.
Sequence of events:
Odd thread gets executed first, then it calls wait() <-- it releases the monitor and now in sleep mode.
Even thread runs, prints msg, and calls notify() <-- here i am not having clear understanding.
When Even thread calls notify(), at that point it has the monitor, so when it calls notify(), does is still own the monitor?
Now, after Even thread calls notify(), then Odd thread gets notified, and hence it starts execution from the point it was sleeping. It is doing some execution and calls notify(), at that points I presume Odd thread is NOT owning the monitor, it calls notify(). So, my question is, does notify() work same whether or not the thread owns the monitor?
It is only when one do the code, one really understands this. I read book and i felt i understood everything, and seems i am back to square one!
The problem here is simply that both threads go straight into wait. Thread 1 gets so, prints value then waits. Thread 2 then gets so, prints value then waits. So both are sleeping away, since nobody is there to notify them. So, a simple fix would be to do so.notify(), right before so.wait(). Then they're not infinitely waiting.
EDIT
Odd thread starts, executes & then waits. Then even thread starts, executes, notifies & then waits. Even thread holds the lock over the monitor until it goes into wait.
When the even thread called on notify, the odd thread awakens & polls for the lock. Once the even thread goes into wait (& releases the lock), then the odd thread can obtain the lock.
If the even thread had not called on notify, then the odd thread would continue to sleep. The even thread would have gone to wait & released the lock. No thread is polling or attempting to obtain the lock, hence the program remains in the suspended state.
The documentation also provides a similar explanation. I hope that clears your doubts.

notify() before exiting the synch'd block?

Is there any use in notify() as the last statement in a sync'd block ?
Eg.: Suppose the following code is running in some thread r,
synchronized(t) {
t.start();
// do stuff using t
t.notify();
}
what would i loose if I remove the line?
t.notify();
Thread r is releasing the lock of t already, and this lock is available to those waiting on it.
The code samples I worked on "behaved" the same with and without the t.notify() call up there.
The only use i can think of is, being somewhat "proactive" in notifying that the monitor of t is being released and those waiting on it will get into BLOCKED state, waiting to acquire it.
However, in this case that notify() is the last statement in the synch'd block, JVM will already know, by exiting the synch'd block, that this lock is released.
This rather is a Q on understanding some specifics on notify() & notifyAll().
TIA.
Please note: I've seen Java notify() run before wait()? and Does the position of the notify() call matter?(Java). This is a different Q than those.
//================================
EDIT: the sample code:
public class T3 {
public static void main(String[] args){
Sum t = new Sum();
synchronized(t) {
t.start();
try {
t.wait();
} catch (InterruptedException ex) {
}
}
System.out.println("Sums up to: " + t.sum);
} // main
}
class Sum extends Thread {
int sum;
public void run() {
synchronized(this) {
for(int i = 1; i <= 55 ; sum += i++);
// notify();
}
}
}
same thing when run() of class Sum is as follows:
public void synchronized run() {
for(int i = 1; i <= 55; sum += i++);
// notify();
}
If you are locking on a thread, and the thread terminates, it sends a notifyAll to whatever threads are waiting on it. See the API documentation for Thread.join:
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.
In your example the notification is the last thing done before the thread finishes executing, so the explicit notification is redundant.
(Note that the API documentation quoted here and Jon Skeet are both recommending you don't lock on a thread object.)
Yes. It allows other threads that are wait()ing on t to run again, instead of waiting for a notify that never comes.

Categories