Reputation: 20856
I'm trying to run a sample thread module using method Synchronization but the results are not as expected.
Since I have synchronized m1(), I would expect thread-1 completely print the values 0...10 and then thread-2 start running.
But, in this case the numbers are printed alternatively...
package threadexample;
public class Test implements Runnable{
public void run(){
m1();
}
public synchronized void m1(){
for (int i = 0; i < 10; i ++){
System.out.println(Thread.currentThread().getName() + " Value of i = " + i);
}
}
Test(String threadname){
super();
}
public static void main(String[] args){
Test a = new Test("A");
Test b = new Test("B");
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t2.start();
}
}
Output:
Thread-0 Value of i = 0
Thread-1 Value of i = 0
Thread-0 Value of i = 1
Thread-1 Value of i = 1
Thread-0 Value of i = 2
Thread-1 Value of i = 2
Thread-0 Value of i = 3
Thread-1 Value of i = 3
Thread-0 Value of i = 4
Thread-1 Value of i = 4
Thread-0 Value of i = 5
Thread-1 Value of i = 5
Thread-0 Value of i = 6
Thread-1 Value of i = 6
Thread-0 Value of i = 7
Thread-1 Value of i = 7
Thread-0 Value of i = 8
Thread-1 Value of i = 8
Thread-0 Value of i = 9
Thread-1 Value of i = 9
Upvotes: 1
Views: 82
Reputation: 21858
The problem with synchronized
on a method is that it locks on this
. In your case you have 2 different instances - each of them has a different this
reference. Using the synchronized
word on a method is the same as doing this:
public void m1() {
synchronized(this) {
// Critical code section here
}
}
If you want to do the lock you described your code should look like this:
public class Test implements Runnable{
private final static Object lock = new Object();
public void run(){
m1();
}
public void m1(){
synchronized(lock) {
for (int i = 0; i < 10; i ++){
System.out.println(Thread.currentThread().getName() + " Value of i = " + i);
}
}
}
Test(String threadname){
super();
}
public static void main(String[] args){
Test a = new Test("A");
Test b = new Test("B");
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t2.start();
}
}
In this case you share the lock between the 2 instances (because it's static) and this way you lock on the same object and have your synchronization the way you wanted it to be.
Upvotes: 1
Reputation: 279960
You've synchronized
an instance method. It will synchronize on the instance itself. However each of your Thread
s is using a different instance, ie. they are each synchronized
on a different object and therefore not blocking each other.
You need to share your Test
instance
Test a = new Test("A");
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
or use synchronized
on a different shared object. You can do this either by passing a lock object as a constructor argument or using a static field reference.
Upvotes: 3