java线程安全之volatale的非原子性(七)
来源:互联网 发布:sap软件咨询顾问 编辑:程序博客网 时间:2024/06/07 22:02
科技快讯
11月16日晚间消息,携程CEO孙洁就亲子园事件相关进展做最终通报,携程前人力资源部副总裁施琦、现任人力资源部副总裁冯卫华已被免职。
正文
volatile关键字虽然拥有多个线程之间的可见性,但是却不具备同步性(也就是原子性),可以算上是一个轻量级的synchronized,性能要比synchronized强很多,不会造成阻塞(在很多开源的架构里,比如netty的底层代码就大量使用volatile,可见 netty性能一定是非常不错的。)这里需要注意:一般volatile用于只针对于多个线程可见的变量操作,并不能代替synchronized的同步功能。
如下案例:
public class VolatileNoAtomic extends Thread { //private static volatile int count; private static AtomicInteger count = new AtomicInteger(0); private static void addCount() { //count++ ; count.incrementAndGet(); System.out.println(Thread.currentThread().getName() + " >>>> " + count); } public void run() { addCount(); } public static void main(String[] args) { VolatileNoAtomic[] arr = new VolatileNoAtomic[100]; for (int i = 0; i < 10; i++) { arr[i] = new VolatileNoAtomic(); } for (int i = 0; i < 10; i++) { arr[i].start(); } }}
打印结果(每一次的打印结果都会是不一样的):
Thread-1 >>>> 3Thread-2 >>>> 3Thread-0 >>>> 3Thread-3 >>>> 4Thread-4 >>>> 5Thread-5 >>>> 6Thread-6 >>>> 7Thread-7 >>>> 8Thread-8 >>>> 9Thread-9 >>>> 10
示例总结
volatile关键字只具有可见性,没有原子性。要实现原子性建议使用atomic类的系列对象,支持原子性操作(注意atomic类只保证本身方法原子性,并不保证多次操作的原子性)
如下案例:
public class AtomicUse { private static AtomicInteger count = new AtomicInteger(0); //多个addAndGet在一个方法内是非原子性的,需要加synchronized进行修饰,保证4个addAndGet整体原子性 /**synchronized*/ public synchronized int multiAdd(){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count.addAndGet(1);//+1 count.addAndGet(2);//+3 count.addAndGet(3);//+6 count.addAndGet(4); //+10 也就是一次加10 return count.get(); } public static void main(String[] args) { final AtomicUse au = new AtomicUse(); List<Thread> ts = new ArrayList<Thread>(); for (int i = 0; i < 10; i++) { ts.add(new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+" >>>> "+au.multiAdd()); } })); } for(Thread t : ts){ t.start(); } }}
打印结果:
Thread-0 >>>> 10Thread-9 >>>> 20Thread-8 >>>> 30Thread-7 >>>> 40Thread-6 >>>> 50Thread-5 >>>> 60Thread-4 >>>> 70Thread-3 >>>> 80Thread-2 >>>> 90Thread-1 >>>> 100
多个addAndGet在一个方法内是非原子性的,需要加synchronized进行修饰,保证4个addAndGet整体原子性
源代码:https://github.com/hfbin/Thread_Socket/tree/master/Thread/sync007
阅读全文
1 0
- java线程安全之volatale的非原子性(七)
- JVM之线程安全、原子性实现
- 破除java神话之三:原子操作都是线程安全的
- 破除java神话之三:原子操作都是线程安全的
- 破除java神话之三:原子操作都是线程安全的
- Java多线程之~~~线程安全容器的非阻塞容器
- Java之HashMap在非线程安全时的行为
- java的volatile关键字之非线程安全
- JAVA多线程——线程安全之原子性,有序性和可见性
- 原子性和线程安全
- 线程安全之可见性、有序性以及原子性
- JAVA的线程安全和非线程安全的区别
- Java 非线程安全
- Java 并发编程(三)为线程安全类中添加新的原子操作
- Java 并发编程(三)为线程安全类中添加新的原子操作
- Count++不是线程安全的 不是原子性的
- 力所能及之java线程安全和非线程安全问题
- Java线程安全和非线程安全
- HTTP的请求过程
- 谷歌浏览器中离线安装.crx扩展名的Chrome插件
- LINUX技巧-查找路径下文件中含有某字符串的文件及其路径
- python基础(字符串相关操作)
- LINUX技巧-查找文件行中值重复的行
- java线程安全之volatale的非原子性(七)
- Java 的布局管理器GridBagLayout的使用方法【图文说明】
- gitlab ee 权限清单
- 简单常用的小代码——猜数字游戏
- django环境安装
- error: failed to push some refs to【问题解决】
- 洛谷p1865区间筛素数
- 16进制,2进制,十进制互相转换
- linux中断流程