5

What happens in the following code? Does the synchronization work? This is an interview question.

class T
{
    public static void main(String args[])
    {
        Object myObject = new Object();
        synchronized (myObject)
        {
            myObject = new Object();
        } // end sync
    }
}
codefx
  • 9,872
  • 16
  • 53
  • 81
  • 4
    your synchronized block being in main and not within a loop, it will only be run once anyway. No point in synchronizing here (unless you call that main from another main, which would be weird). – assylias Jun 21 '12 at 08:58

6 Answers6

4

Each time you enter the synchronized block, you synchronize on a different object. Most of the time this will not do anything except confuse you, but there is a small chance that two threads will see the same object and wait.

For this reason any code analysers will give you a warning if you are synchronizing on a field which is not final.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

It still releases the same monitor that was acquired, but any other code which also locks using myObject (impossible here as it's a local variable, making the synchronization fundamentally pointless) would start to use the new object.

Don't forget that synchronization is applied to objects (or rather, the monitors associated with objects) - not variables. The monitor being acquired/released just depends on the value of the expression when the start of the synchronized block is reached. The expression is not re-evaluated at the end of the synchronized block.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

No, it doesn't work. Whenever a new thread comes in, a new myObject is created. Particularly now that myObject is a local variable!

It wouldn't work even if myObject is a class member since you would be changing the object you're locking on. See question about synchronization of non-final field for longer explanation.

Community
  • 1
  • 1
Joonas Pulakka
  • 36,252
  • 29
  • 106
  • 169
0

i don't see the reason behind this code since the Object is not shared by any threads. Removing the synchronized block will have no effect on the real outcome in any case. It will just make your code run faster

MaVRoSCy
  • 17,747
  • 15
  • 82
  • 125
0

You need obtain myObject's lock first,if this lock was blocked,you have to wait until the lock is released.

Synchronization requires multi-thread environment.But your code seems nothing to do with concurrent.So I am sorry to tell you that there is NOTHING going to happen.

Tiny Lin
  • 258
  • 1
  • 2
  • 7
0

Run the Code And analyse the result.

public class Test {
    static Foo o = new Foo(0);
    static class Foo {
        private int i = 0;
        Foo(int i) {
            this.i = i;
        }
        public void addOnce() {
            this.i++;
        }
        public String toString() {
            return String.valueOf(i);
        }
    }
    public static void main(String args[]) {
        test1();
        try {Thread.sleep(10000);} catch (Exception e) {}
        test2();
    }
    public static void test1() {
        Runnable r = new Runnable() {
            public void run() {
                synchronized (o) {
                    System.out.println("1------>"+o);
                    o = new Foo(1);
                    try {Thread.sleep(3000);} catch (Exception e) {}
                    System.out.println("1------>"+o);
                }
            }
        };
        new Thread(r).start();
        new Thread(r).start();
    }
    public static void test2() {
        Runnable r = new Runnable() {
            public void run() {
                synchronized (o) {
                    System.out.println("2------>"+o);
                    o.addOnce();
                    try {Thread.sleep(3000);} catch (Exception e) {}
                    System.out.println("2------>"+o);
                }
            }
        };
        new Thread(r).start();
        new Thread(r).start();
    }
}