【问题标题】:what is the difference between synchronized and static synchronized同步和静态同步有什么区别
【发布时间】:2014-06-19 10:30:26
【问题描述】:

嗯,我发现这个问题回答了好几次。答案也很常见。 静态同步方法锁定,同步方法锁定实例本身。

并且同一类的两个不同线程不能同时调用两个不同的同步方法。如果呼叫则一个被阻止。 静态同步方法也会发生同样的事情。所以在我看来,这两种情况都显示出相同的可用性。如果有人在这两种方法的可用性情况下标记出这两种方法的差异,那将非常有帮助。

【问题讨论】:

    标签: java multithreading static synchronized


    【解决方案1】:

    同一类的两个不同线程不能同时调用两个不同的同步方法。

    这是一个非常普遍的误解,但并非总是如此。这是总是正确的:没有两个线程可以同时在同一个对象上synchronized

    当在实例方法上使用synchronized 关键字时,该方法的整个主体在this 上同步。假设我们有一个类:

    class Foo {
        synchronized void doSomething() { ... }
        synchronized void doSomethingElse() { ... }
    }
    

    这实际上是一种简写方式:

    class Foo {
        void doSomething() { synchronized (this) { ... }}
        void doSomethingElse() { synchronized (this) { ... }}
    }
    

    现在假设我们有两个类的实例:

    final Foo f1 = new Foo(...);
    final Foo f2 = new Foo(...);
    

    线程 B 在 f1.doSomethingElse() 中时线程 A 无法进入 f1.doSomething(),但线程 A 可以在线程 B 在 f2.doSomethingElse() 中。那是因为 f1 和 f2 是 不同的 对象。 synchronized 关键字仅防止两个或多个线程在 same 对象上同步。

    static 方法的情况略有不同。本声明:

    class Bar {
        static synchronized void doSomething() { ... }
        static synchronized void doSomethingElse() { ... }
    }
    

    与此声明相同:

    class Bar {
        static void doSomething() { synchronized(Bar.class) { ... }}
        static void doSomethingElse() { synchronized(Bar.class) { ... }}
    }
    

    static 方法无法在 this 上同步,因为没有为静态方法定义 this。而是在类对象上同步静态方法。

    在这种情况下,永远不可能有一个线程在 Bar.doSomething() 中,而另一个线程在 Bar.doSomethingElse() 中运行,因为这两种方法在相同 对象(Bar.class 对象。)

    【讨论】:

      【解决方案2】:

      在下面的代码中

      • 不允许两个线程同时进入b方法。
      • 不允许两个线程同时进入t1.a()方法。
      • 一个线程调用t1.a()不会干扰另一个线程调用t2.a()

        public class Test {
        
            synchronized void a() {
        
            }
        
            static synchronized void b() {
        
            }
        
            public static void main(String args[]) {
                final Test t1 = new Test();
                final Test t2 = new Test();
                // Some threads that just mess with the test objects.
                Thread test1 = new Thread() {
                    public void run() {
                        while (true) {
                            t1.a();
                        }
                    }
                };
                Thread test2 = new Thread() {
                    public void run() {
                        while (true) {
                            t2.b();
                        }
                    }
                };
                Thread test3 = new Thread() {
                    public void run() {
                        while (true) {
                            t1.a();
                            t1.b();
                            t2.a();
                            t2.b();
                        }
                    }
                };
                test1.start();
                test2.start();
                test3.start();
            }
        }
        

      【讨论】:

      • 谢谢。我现在明白了
      猜你喜欢
      • 1970-01-01
      • 2011-05-22
      • 2011-01-09
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多