此文已由作者赵计刚授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
注:在阅读本章之前,先要了解Java内存模型,见上一章《附1 Java内存模型与共享变量可见性》,链接如下:
http://www.cnblogs.com/java-zhao/p/5124725.html
1、volatile用法
具体的用法可以参照《第二章 ConcurrentHashMap源码解析》中的Segment内部类的count属性,可以看看多线程情况下怎样对其进行操作的,具体链接如下;
http://www.cnblogs.com/java-zhao/p/5113317.html
或者可以参照《第三章 CopyOnWriteArrayList源码解析》中CopyOnWriteArrayList的底层数组,具体链接如下;
http://www.cnblogs.com/java-zhao/p/5121944.html
2、具体的实现原理
说人话:
通过上边这样模式,每个线程拿到的volatile变量值都是最新的。
注意:
volatile无法实现原子性:
eg.
private volatile int count = 0;
假设现在有两条线程分别对count执行加1操作,那么期待的结果最后count==2,但是看下边的分析:
假设有如下流程:
1)线程a获取了count==0;
2)线程b获取了count==0;
3)线程b对count+1,之后写入主内存count==1;
4)线程a对count+1,之后写入主内存count==1;
结果count==1而非count==2,原因就是线程a获取count后,volatile不能实现原子性,这个时候b也能去操作count。
想要实现原子性,使用synchronized去锁住增加方法,或者使用ReentrantLock去锁住增加代码;当然,以上场景使用AtomicInteger更好。
3、volatile使用场景
所以说,volatile只能实现部分线程安全(实际上只能实现可见性)。 如果volatile用得好的话,比synchronized强不少,因为不需要上下文切换。
注:
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请点击。