加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 不可变对象是线程安全的,但为什么呢?

发布时间:2020-12-15 07:37:52 所属栏目:Java 来源:网络整理
导读:如果一个线程通过创建其对象来创建填充不可变类的引用变量,并且在第一个线程完成之前第二次另一个线程启动并创建不可变类的另一个对象,则不可变类的使用不会是线程不安全? 创建一个不可变对象也表示所有字段都标记为final …..“如果对新创建的实例的引用从
如果一个线程通过创建其对象来创建填充不可变类的引用变量,并且在第一个线程完成之前第二次另一个线程启动并创建不可变类的另一个对象,则不可变类的使用不会是线程不安全?
创建一个不可变对象也表示所有字段都标记为final …..“如果对新创建的实例的引用从一个线程传递到另一个线程而没有同步,则可能需要确保正确的行为”
他们是否试图说另一个线程可能会将引用变量重新指向不可变类的某个其他对象,那么线程将指向不同的对象而使状态不一致?

解决方法

实际上,不可变对象总是线程安全的,但它的引用可能不是.

困惑??你不应该: –

回到基础:
线程安全只是意味着两个或多个线程必须协同工作在共享资源或对象上.他们不应该忽略任何其他线程所做的更改.

现在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块/方法中访问它们.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读