【问题标题】:What happens if synchronization variable is reassigned in java?如果在java中重新分配同步变量会发生什么?
【发布时间】:2012-06-23 11:36:28
【问题描述】:

下面的代码会发生什么?同步有效吗?这是一道面试题。

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

【问题讨论】:

  • 您的同步块在 main 中而不是在循环中,无论如何它只会运行一次。在这里同步没有意义(除非你从另一个主服务器调用那个主服务器,这会很奇怪)。

标签: java synchronization


【解决方案1】:

每次进入同步块时,都会在不同的对象上进行同步。大多数情况下,这只会让你感到困惑,但有很小的机会两个线程会看到同一个对象并等待。

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      即使myObject 是类成员,它也不起作用,因为您将更改您锁定的对象。请参阅有关synchronization of non-final field 的问题以获得更详细的解释。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          你需要先获取myObject的锁,如果这个锁被阻塞了,你必须等到锁被释放。

          同步需要多线程环境。但是你的代码似乎与并发无关。所以很抱歉告诉你,不会发生任何事情。

          【讨论】:

            【解决方案6】:

            运行代码并分析结果。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-12-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-11-13
              相关资源
              最近更新 更多