谷歌凌空单身真的线程安全吗?

时间:2015-08-20 10:33:24

标签: java android multithreading android-volley

在android tranning Use a Singleton Pattern

public static synchronized MySingleton getInstance(Context context) {
    if (mInstance == null) {
        mInstance = new MySingleton(context);
    }
    return mInstance;
}

我认为它仍然不是线程安全的。 如果Object A getInstanceObject B同步执行getInstance,它仍会中断锁定,并创建两个mInstance。 因为synchronized for method仅适用于来自不同线程的ONE对象,而不适用于2个对象。

那么我是否有错误的理解,或者下面的代码比原始代码更安全?

public static synchronized MySingleton getInstance(Context context) {
  synchronized(MySingleton.class) 
  { 
     if (mInstance == null) {
        mInstance = new MySingleton(context);
     }
  }
    return mInstance;
}

1 个答案:

答案 0 :(得分:1)

你的两个例子完全相同。

此:

class Foobar {
    static synchronized mumble(...) { doSomething(); }
}

只是写作的简写方式:

class Foobar {
    static mumble(...) { 
        synchronized(Foobar.class) { doSomething(); }
    }
}

类似的规则适用于非静态方法。这样:

class Foobar {
    synchronized mumble(...) { doSomething(); }
}

只是写作的简写方式:

class Foobar {
    mumble(...) { 
        synchronized(this) { doSomething(); }
    }
}

我不确定我是否真的理解你的问题,但也许你确实有“错误的理解”。

我不喜欢快捷方式,因为同步的方法引起了人们对方法不是我们想要通过同步保护的事实的注意力。我们想要保护的是数据

当一个线程无法更新某些数据集而不创建其他线程不允许看到的临时无效状态时,我们使用同步。我们在创建无效状态的代码周围打了一个synchronized块,我们还在{em>同一个对象上围绕每个代码片段同步的synchronized块,这些代码不能是允许看到无效状态。

JVM永远不会允许同时在同一个对象上同步两个线程,所以如果我们做的一切都正确,那么除了临时创建它之外,不会允许任何线程看到无效状态。