Reputation: 152
I have doubt regarding the synchronized block. After executing the below code i m geeting output as:
Inside run=>thread 2
Inside run=>thread 1
Inside run=>thread 1
Inside run=>thread 2
Inside run=>thread 2
Inside run=>thread 1
Inside run=>thread 2
Inside run=>thread 1
Inside run=>thread 1
Inside run=>thread 2
i was expecting output as only one thread will execute the synchronized block first and then only second thread will get access of synchornized block. may be i have understand the concept wrong?
package com.blt;
public class ThreadExample implements Runnable {
public static void main(String args[])
{
System.out.println("A");
Thread T=new Thread(new ThreadExample());
Thread T1=new Thread(new ThreadExample());
System.out.println("B");
T.setName("thread 1");
T1.setName("thread 2");
System.out.println("C");
T.start();
System.out.println("D");
T1.start();
}
synchronized public void run()
{
for(int i=0; i<5; i++)
{
try
{
System.out.println("Inside run=>"+Thread.currentThread().getName());
Thread.currentThread().sleep(2000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
Upvotes: 1
Views: 1166
Reputation: 80593
Each of your threads is synchronizing on different objects. So yes, they will not lock each other out. But more importantly, the run
method is defined for the Runnable
interface without a synchronization modifier, and you should not be adding one to it (as you can already see, it did not have the effect you thought it would).
The key thing to remember is that when you use the synchronized modifier on a method:
public synchronized void someMethod();
It is effectively the same thing as using synchronized(this)
. In both cases you are locking on the objects monitor. If you have multiple objects, you have multiple monitors.
Here is a modified version of your own example, that will work more as you expected. It uses a common object monitor (in this case, your class itself), so that the synchronization works as expected:
public class ThreadExample implements Runnable {
public static void main(String args[]) {
System.out.println("A");
Thread T = new Thread(new ThreadExample());
Thread T1 = new Thread(new ThreadExample());
System.out.println("B");
T.setName("thread 1");
T1.setName("thread 2");
System.out.println("C");
T.start();
System.out.println("D");
T1.start();
}
public void run() {
synchronized (ThreadExample.class) {
for (int i = 0; i < 5; i++) {
try {
System.out.println("Inside run=>"
+ Thread.currentThread().getName());
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Upvotes: 4
Reputation: 328568
Your problem is that 2 synchronized blocks are not mutually exclusive if they don't lock on the same monitor.
Remember that a synchronized method locks on the this
monitor - your code is equivalent to:
public void run() {
synchronized(this) {
//your code here
}
}
Since you create two instances of ThreadExample
they each have a distinct this
.
You can solve your issue by using the same lock in both threads, for example:
public void run() {
synchronized(ThreadExample.class) {
//your code here
}
}
or even better, create only one instance of ThreadExample
as pointed out by Quoi.
Upvotes: 3
Reputation: 864
You are creating two instance of the class, and you are synchronising on class, hence they will run independently, since there is no common lock. They will keep running separately.
Upvotes: 0
Reputation: 16824
Uhh, you're synchronizing each thread's run method. Thread1 will not attempt to run Thread2's run method, and viceversa. That's why it's effectively the same as not synchronizing at all.
Upvotes: 0
Reputation: 41200
You have created two Object of ThreadExample
, so each thread has different synchronized
method.
Create a single Object and pass the reference to the thread, you will see synchronized effect.:)
ThreadExample thex = new ThreadExample();
Thread T=new Thread(thex);
Thread T1=new Thread(thex);
Here both thread will use same synchronized
method.
Upvotes: 1