1

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

2 Answers 2

3

You've synchronized an instance method. It will synchronize on the instance itself. However each of your Threads 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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.