欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

不可变对象加锁操作不起作用的探究

时间:2023-06-09
并发中对于不可变对象加锁问题,例如String和基本类型的包装类

public static void main(String[] args) { List list = new ArrayList<>(); for (int j = 0; j < 2; j++) { Thread thread = new Thread(() -> { for (int k = 0; k < 5000; k++) { synchronized (i) { i++; } } }, "" + j); list.add(thread); } list.stream().forEach(t -> t.start()); list.stream().forEach(t -> { try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); log.debug("{}", i);//大概率比10000小,基本可以说一定 }

​ 我们也加了锁,按理来说结果应该是10000,那为什么比10000小呢,这里就涉及到封装类的一些特性,不可变对象,String和基本包装类型都是final,也就是不可变对象。虽然看上去它可以改变值,但实际上,他返回了一个新的对象。

​ 在Java中,Integer使用不变对象。也就是对象一旦被创建,就不可能被修改。也就是说,如果你有一个Integer代表1,那么它就永远是1,你不可能改变Integer的值,使它位。那如果你需要2怎么办呢?也很简单,新建一个Integer,并让它表示2即可。

​ 同时,在jdk对于基本类型和包装类的转换来说。i的值具体应该这样。

//内部实际上创建了一个新的Integer对象i = Integer.valueOf(i.intValue()+1);

​ 这里大概已经知道为什么了,原因很简单,每次++实际上返回了一个新的Integer对象,也就是说,加锁可能加的不是同一把锁,并无效果。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。