ealeon
ealeon

Reputation: 12452

Java will synchronized block if changed?

private Object x = new Object();

public void doA() {
   synchronized(x){
       x = new Object();
       //do something
    }
}

public void doB() {
    synchronized(x) {
        //do something 
    }
}

lets say doA() and doB() was called simultaneously but doA() is proceeding first. so B will be blocked until doA() is completed

is this true even if doA() modifies x in the x = new x call? or after this line x = new x in doA() doB() will no longer be blocked because x has changed?

Upvotes: 3

Views: 597

Answers (3)

Mike Pone
Mike Pone

Reputation: 19320

My own curiosity got the best of me and I wrote this test to verify what happens. The lock is still held on the original reference and does not change.

import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class Test {

    private static Object x = new Object();

    public static void main(String[] args) throws Exception {
        Test a = new Test();
        Test b = new Test();

        Thread t = new Thread(a.new MyRunnable());
        t.start();
        Thread.sleep(100);
        b.doB();
    }

    public void doB() {
        System.out.println("here b");
        synchronized (x) {
            System.out.println("here sync b");
        }
        System.out.println("here done sync b");
    }

    public class MyRunnable implements Runnable {

        public MyRunnable() {
        }

        public void run() {
            System.out.println("here a");
            synchronized (x) {
                System.out.println("here sync a");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }

                x = new Object();

                System.out.println("here new object a");
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("here after sleep a");
            }
            System.out.println("here done sync a");
        }
    }

}

Output is below. Clearly the lock is still held on to the original reference even after reassignment.

here a
here sync a
here b
here new object a
here after sleep a
here done sync a
here sync b
here done sync b

Upvotes: 2

Kröw
Kröw

Reputation: 319

What happens would really depend on how quickly doA() gets run:

If doA() changes the value of x before doB() reaches its synchronized block, then doB() will lock on the new object that doA() created.

If doB() is speedy and the synchronized(x) part gets evaluated before doA() can change the value of x, then doB() will have to wait until doA()'s synchronized block finishes.

Explanation

Whenever Java gets to the synchronized(x) code in either method, it evaluates the variable x, and that variable gives Java an object. So Java then tries to lock on that object, and stay locked on that object. Or, if there's already a lock on that object, it will wait for the lock to go away. (Whenever Java reaches the synchronized(x) code, it takes the value of the variable and ignores forgets the variable itself, so you can change the variable as you please afterwards, but locking and lock checking still happen on the variable's previous value.)

Upvotes: 4

Rahul Vedpathak
Rahul Vedpathak

Reputation: 1436

I think the doA() method will still hold the lock on old "x". Other thread waiting for lock on "x" won't be notified unless the thread holding is finished processing synchronized block. Once synchronized block is completed, threads will fight to acquire lock on new instance of x.

Upvotes: 1

Related Questions