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对象,也就是说,加锁可能加的不是同一把锁,并无效果。



