线程安全的延迟初始化

时间:2016-01-27 18:50:27

标签: java thread-safety lazy-initialization

我已经阅读了关于线程安全的延迟初始化的内容,我看一下String类中hashCode方法的实现。显然这个方法是线程安全的,我为另一个类(不可变)创建了我自己的版本。

import static java.util.UUID.randomUUID

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.commonsware.myapplication"
        minSdkVersion 21
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        debug {
            buildConfigField "String", "FOO", '"'+randomUUID()+'"'
        } 

        release {
            buildConfigField "String", "FOO", '"a49f05b4-f55a-4066-a107-9098c9350f43"'
        }
    }
}

我的问题是:它真的是线程安全的吗?我不明白为什么。 我没有看到什么阻止线程进入该方法,而另一个仍然在里面,但也许它错了。

2 个答案:

答案 0 :(得分:2)

您看到的代码可能效率低下。可能发生的情况是多个线程同时进入hashCode()函数并且它们都计算哈希码而不是只计算哈希码中的一个,而其他线程等待结果。

因为String是不可变的,所以这不是问题。如果对象是可变的,则需要在其hashCode()函数中进行同步(因为在hashCode()内部可以更改对象的状态。

答案 1 :(得分:1)

正如@JB Nizet指出的那样,主要的问题是你可能有一个非空数组,其哈希值恰好是$scope。你需要能够区分“Hash is really 0”和“Hash is unknown”。您可以使用可为空的0

Integer