JDK源码笔记之Integer深度解析以及并发下错误的加锁方式踩坑笔记
Posted 不清不慎的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK源码笔记之Integer深度解析以及并发下错误的加锁方式踩坑笔记相关的知识,希望对你有一定的参考价值。
对于Java的数据类型Integer,大多人认为不就很简单的一个数据类型吗?是的,我以前也不在意,感觉关于integer没什么可说,但是不深入源码你永远不知道它给你留下的坑。 ------------------------------------------------------------------------**一、谈谈integer留下的坑**
首先我们来看一段代码。
package cn.shinelon.jvm;public class TestInteger { public static void main(String[] args) { Integer i1=1; Integer i2=1; System.out.println(i1==i2); Integer i3=129; Integer i4=129; System.out.println(i3==i4); } }
上面的代码只要接触过Java的人都能够看明白,不用过多解释,比较两个integer变量是否相等。估计一眼就可以看出答案,但是对不对呢?可能与大多人所预料的结果大相径庭,大多人觉得两个结果输出一定都是true,但是我们来看看运行结果。
这个结果着实让很多大吃一惊,为什么第二个会是false呢,i3和i4不都是129吗?怎么不相等了,下面来让我们看看这其中的原因:使用javap -c命令反编译class文件:
我们可以看到Integer i1,i2,i3,i4这些语句都调用了Integer.valueOf()方法,因此,我们来看看valueOf()方法的源码。
package cn.shinelon.jvm;public class TestInteger { public static void main(String[] args) { Integer i1=1; Integer i2=1; System.out.println(i1==i2); Integer i3=129; Integer i4=129; System.out.println(i3==i4); } }
对于上面这段代码运行结果,这里就不卖关子了,理论情况下很多人看上去认为结果是20000,但是事实不是这样,结果会等到一个比20000小很多的数,比如12698,这是为什么呢?我们可以按照上面的方式使用javap命令反编译run()方法里面的代码,发现它任然调用了valueof方法,这就很好解释了,因为在该方法里它会在超出缓冲区范围后new一个新的对象,也就是说synchronized关键字加在两把不同的锁上面,因此两个线程不能同步,所以结果会比20000小很多。怎么解决以上的问题呢?很简单,只需要将上面代码改为synchronized(instance)即可。上面是个人对Integer的一些小小的总结以及解读,如有不足之处还请指教!
以上是关于JDK源码笔记之Integer深度解析以及并发下错误的加锁方式踩坑笔记的主要内容,如果未能解决你的问题,请参考以下文章