java不可变对象泄漏_java – 不可变对象是线程安全的,但为什么...

探讨了不可变对象如String在多线程环境下的线程安全性问题,并解释了即使不可变对象本身是线程安全的,其引用也可能导致线程不安全的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

困惑??你不应该: –

回到基础:

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值