举例来说,一个线程正在通过创建不可变类的对象来创建和填充不可变类的引用变量,而另一个线程在第一个线程完成并创建不可变类的另一个对象之前启动,那么不可变类的用法不是线程吗不安全?
创建不可变对象还意味着所有字段都必须标记为final。
如果引用了,可能有必要确保正确的行为
新创建的实例从一个线程传递到另一个线程,无需
同步
他们是否想说另一个线程可以将引用变量重新指向不可变类的某个其他对象,这样线程将指向不同的对象,从而导致状态不一致?
实际上,不可变对象始终是线程安全的,但其引用可能不是。
使困惑??你不应该:-
回到基本:
线程安全仅仅意味着两个或多个线程必须在共享资源或对象上协调工作。它们不应该覆盖任何其他线程所做的更改。
现在 String 是一个不可变的类,每当线程尝试更改它时,它最终都会创建一个新对象。因此,即使同一个线程也无法对原始对象进行任何更改,而谈论另一个线程就像去 Sun 一样,但这里的问题是,通常我们使用相同的旧引用来指向新创建的对象。
当我们编写代码时,我们仅使用引用来评估对象中的任何更改。
声明一:
字符串str =“123”; // 最初字符串共享给两个线程
声明2:
str = str+"第一个线程"; // 由线程一执行
声明3:
str=str+"第二线程"; // 由线程二执行
现在,由于没有同步、易失性或最终关键字告诉编译器跳过使用其智能进行优化(任何重新排序或缓存事物),因此可以按以下方式运行此代码。
- 加载Statement2,因此str =“123”+“FirstThread”
- 加载Statement3,所以str = "123"+"SecondThread"
- 存储Statement3,因此str =“123SecondThread”
- 存储Statement2,因此str =“123FirstThread”
最后是引用 str="123FirstThread" 中的值,并且有时如果我们假设幸运的是我们的 GC 线程正在休眠,那么我们的不可变对象仍然原封不动地存在于字符串池中。
因此,不可变对象始终是线程安全的,但它们的引用可能不是。为了使它们的引用线程安全,我们可能需要从同步块/方法访问它们。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)