Reputation: 53
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?
Upvotes: 1
Views: 173
Reputation: 533870
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.
}
Upvotes: 1
Reputation: 8363
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.
You wanted to visualize what is happening so I'll do it here.
for
loop. Then it calls P.pp()
.P.pp()
is called from first thread, it locks the P
object.P
.synchronize
block before the first thread exits, it will wait (blocked).P.pp()
again.Upvotes: 2
Reputation: 902
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
Upvotes: 1
Reputation: 1759
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...
Upvotes: 1