在函数中通过类名同步将在扩展类中有效吗?

时间:2012-01-19 22:19:07

标签: java synchronized

我在基类中有一个方法foo使用Synchronized(类名),以及两个扩展基类的类A和B.如果我从一个实例调用foo并且两个不同线程中的B实例将被同步。这是一个示例代码:

class BaseClass { 
        void foo() {
        synchronized(BaseClass.class)   
            // do something like increment count 
        }   
    }


    class A extends BaseClass {
    }


    class B extends BaseClass {
    }

    A a = new A(); 
    B b = new B();
    //in thread 1
    a.foo() ; 
    //in thread 2
    b.foo() ;

3 个答案:

答案 0 :(得分:5)

是的,它将在扩展BaseClass的所有类的所有实例(包括BaseClass本身)之间同步。 BaseClass.class引用基本上是整个类加载器的单个引用。你真的想要吗?

通常,当需要同步时,静态方法应该在静态的东西上同步,而实例方法应该在与实例相关的东西上同步。我个人不喜欢在thisClass引用上进行同步 - 因为这两个引用都可以在其他地方使用,因此其他代码可以在同一个监视器上同步,这使得很难推断同步。相反,我倾向于:

public class Foo {
    private final Object instanceLock = new Object();

    public void doSomething() {
        synchronized (instanceLock) {
            // Stuff
        }
    }
}

public class Bar {
    private static final Object staticLock = new Object();

    public static void doSomething() {
        synchronized (staticLock) {
            // Stuff
        }
    }
}

(我通常只是使用lock作为名称;为了清楚起见,我在这里更加明确。)

答案 1 :(得分:2)

是的,你正在同步同步。

答案 2 :(得分:0)

是。它是同步的,即使不保证线程执行顺序。