一、前情回顾
上篇文章给大家聊了一下volatile的原理,具体参见:《入坑两个月自研非外包创业公司,居然让我搞懂了volatile!》
这篇文章给大家聊一下java并发包下的CAS相关的原子操作,以及Java 8如何改进和优化CAS操作的性能。
因为Atomic系列的原子类,无论在并发编程、JDK源码、还是各种开源项目中,都经常用到。而且在Java并发面试中,这一块也属于比较高频的考点,所以还是值得给大家聊一聊。
二、场景引入,问题凸现
好,我们正式开始!假设多个线程需要对一个变量不停的累加1,比如说下面这段代码:
实际上,上面那段代码是不ok的,因为多个线程直接这样并发的对一个data变量进行修改,是线程不安全性的行为,会导致data值的变化不遵照预期的值来改变。
举个例子,比如说20个线程分别对data执行一次data++操作,我们以为最后data的值会变成20,其实不是。
最后可能data的值是18,或者是19,都有可能,因为多线程并发操作下,就是会有这种安全问题,导致数据结果不准确。
至于为什么会不准确?那不在本文讨论的范围里,因为这个一般只要是学过java的同学,肯定都了解过多线程并发问题。
三、初步的解决方案:synchronized
所以,对于上面的代码,一般我们会改造一下,让他通过加锁的方式变成线程安全的:
这个时候,代码就是线程安全的了,因为我们加了synchronized,也就是让每个线程要进入increment()方法之前先得尝试加锁,同一时间只有一个线程能加锁,其他线程需要等待锁。
通过这样处理,就可以保证换个data每次都会累加