简体   繁体   English

如果在Java中重新分配了同步变量会怎样?

[英]What happens if synchronization variable is reassigned in java?

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
    }
}

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 . 因此,如果您在不是final的字段上进行同步,则任何代码分析器都会向您发出警告。

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. 它仍会释放与获取的监视器相同的监视器,但是任何其他使用myObject也会锁定的代码(此处是局部变量,因此从根本上讲毫无意义,因此无法使用)将开始使用新对象。

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. 在同步块的末尾重新计算该表达式。

No, it doesn't work. 不,它不起作用。 Whenever a new thread comes in, a new myObject is created. 每当有新线程进入时,都会创建一个新的myObject Particularly now that myObject is a local variable! 特别是现在myObject是一个局部变量!

It wouldn't work even if myObject is a class member since you would be changing the object you're locking on. 即使myObject是类成员也不起作用,因为您将更改锁定的对象。 See question about synchronization of non-final field for longer explanation. 有关更多说明,请参见有关非最终字段同步的问题。

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 它将使您的代码运行更快

You need obtain myObject's lock first,if this lock was blocked,you have to wait until the lock is released. 您需要首先获取myObject的锁,如果此锁被阻止,则必须等到锁释放后才能使用。

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. 同步需要多线程环境,但是您的代码似乎与并发无关,所以很遗憾地告诉您,什么都不会发生。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM