实际上,不可变对象总是线程安全的,但它的引用可能不是.
困惑??你不应该: –
回到基础:
线程安全只是意味着两个或多个线程必须协同工作在共享资源或对象上.他们不应该忽略任何其他线程所做的更改.
现在String是一个不可变类,只要一个线程试图改变它,它就会最终创建一个新对象.因此,即使是相同的线程也无法对原始对象进行任何更改.谈论另一个线程就像去太阳,但这里的问题是,通常我们使用相同的旧引用来指向新创建的对象.
当我们执行代码时,我们仅使用引用来评估对象中的任何更改.
声明1:
String str =“123”; //最初将字符串共享到两个线程
声明2:
str = str“FirstThread”; //由第一个线程执行
声明3:
str = str“SecondThread”; //由第二个线程执行
现在由于没有同步,易失或最终关键字告诉编译器跳过使用其智能进行优化(任何重新排序或缓存的东西),此代码可以按以下方式运行.
>加载Statement2,所以str =“123”“FirstThread”
>加载Statement3,所以str =“123”“SecondThread”
>存储Statement3,所以str =“123SecondThread”
>存储Statement2,所以str =“123FirstThread”
最后参考str =“123FirstThread”中的值,如果我们假设幸运的是我们的GC线程正在休眠,那么我们的不可变对象在我们的字符串池中仍然不存在.
因此,Immutable对象始终是线程安全的,但它们的引用可能不是.为了使它们的引用成为线程安全的,我们可能需要从synchronized块/方法中访问它们.