如果在java中重新分配同步变量会发生什么?

时间:2012-06-21 08:55:49

标签: java synchronization

以下代码会发生什么?同步是否有效?这是一个面试问题。

class T
{
    public static void main(String args[])
    {
        Object myObject = new Object();
        synchronized (myObject)
        {
            myObject = new Object();
        } // end sync
    }
}

6 个答案:

答案 0 :(得分:4)

每次进入同步块时,都会同步另一个对象。大多数情况下,除了让您感到困惑之外,这不会做任何事情,但是两个线程很可能会看到相同的对象并等待。

因此,如果您要在不是final的字段上进行同步,任何代码分析器都会向您发出警告。

答案 1 :(得分:1)

它仍然释放了获取的同一个监视器,但是任何其他代码也使用myObject锁定(这里不可能,因为它是一个局部变量,使同步基本没有意义)将开始使用新对象。 / p>

不要忘记同步应用于对象(或者更确切地说,与对象关联的监视器) - 而不是变量。正在获取/释放的监视器取决于达到同步块的 start 时表达式的值。表达式是在同步块结束时重新评估

答案 2 :(得分:0)

不,它不起作用。每当有新线程进入时,都会创建一个新的myObject。特别是现在myObject是一个局部变量!

即使myObject是类成员也不会起作用,因为您要更改要锁定的对象。有关详细说明,请参阅有关synchronization of non-final field的问题。

答案 3 :(得分:0)

我没有看到此代码背后的原因,因为任何线程都不共享Object。在任何情况下,删除同步块都不会影响实际结果。它只会让你的代码运行得更快

答案 4 :(得分:0)

首先需要获取myObject的锁定,如果此锁定被阻止,则必须等到锁定被释放。

同步需要多线程环境。但是你的代码似乎与并发无关。所以我很遗憾地告诉你,没有任何事情会发生。

答案 5 :(得分:0)

运行代码并分析结果。

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();
    }
}