volatile修饰全局变量,可以保证线程并发安全吗?
今天被人问到volatile能不能保证并发安全?
呵,这能难倒我?
直接上代码:
public class ThreadTest {
// 使用volatile修饰变量
private static volatile int num = 0;
public static void main(String[] args) throws InterruptedException {
// 循环创建10个线程并执行,每个线程内对volatile修饰的num进行递增
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int ii = 0; ii < 1000; ii++) {
autoIncrement();
// autoIncrementLock();
// System.out.println(num); 这是一个彩蛋,猜猜看sout打印会不会影响结果?
}
}).start();
}
// 睡眠3秒以等待每个线程内递增结束
Thread.sleep(3000);
System.out.println("最终结果为:"+num);
}
// 无锁递增
private static void autoIncrement() {
num++;
}
// 使用synchronized修饰递增方法,给其上锁
private static synchronized void autoIncrementLock() {
num++;
}
}
期望最终值:
10 * 1000 = 10000
运行无锁autoIncrement()三次,结果分别为:
第一次:8666
第二次:7767
第三次:9084
运行被synchronized修饰的方法三次,结果分别为:
第一次:10000
第二次:10000
第三次:10000
分析:
10个线程对volatilei修饰的num++,会被编译成以下三步:
- 获取num的值;
- 执行num+1;
- 将结果赋值给num。
volatile关键字只能保证可见性,并不能保证原子性。
结论:
volatile关键字只能保证这3步在编译后指令不会被重新排序,并不能保证多个线程并发的数据安全。建议在方法上加上synchronized修饰或配合其他Lock锁使用。
volatile修饰全局变量,可以保证线程并发安全吗?的更多相关文章
- volatile修饰全局变量,可以保证并发安全吗?
今天被人问到volatile能不能保证并发安全? 呵,这能难倒我? 上代码: //电脑太好,100线程起步~public class ThreadTest { private static volat ...
- 两个线程并发执行以下代码,假设a是全局变量,那么以下输出______是不可能的?
3.两个线程并发执行以下代码,假设a是全局变量,那么以下输出______是不可能的? void foo(){ ++a; printf("%d ",a);}A.3 2 ...
- 【Java并发编程】6、volatile关键字解析&内存模型&并发编程中三概念
volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...
- volatile关键字解析&内存模型&并发编程中三概念
原文链接: http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java5之前,它是一个 ...
- volatile关键字的详解-并发编程的体现
xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!! 参 ...
- 除了Synchronized关键字还有什么可以保证线程安全?
除了Synchronized关键字还有什么可以保证线程安全? 日常使用Java开发时,多线程开发,一般就用Synchronized保证线程安全,防止并发出现的错误和异常,那么 除了Synchr ...
- java--加强之 Java5的线程并发库
转载请申明出处:http://blog.csdn.net/xmxkf/article/details/9945499 01. 传统线程技术回顾 创建线程的两种传统方式: 1.在Thread子类覆盖的r ...
- volatile是否就是原子性/线程同步的
在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...
- Java多线程(四) —— 线程并发库之Atomic
一.从原子操作开始 从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作,因此首先从这里开始). 很多情况下 ...
- java中volatile关键字的含义--volatile并不能做到线程安全
在Java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...
随机推荐
- 分布式Session解决方案详解
4种分布式session解决方案 cookie和session的区别和联系 cookie是本地客户端用来存储少量数据信息的,保存在客户端,用户能够很容易的获取,安全性不高,存储的数据量小session ...
- postman环境设置以及参数传递
通常一个公司项目有不同的环境(开发环境,测试环境,上线环境),在做测试时候,有可能会遇到接口改变之类的,postman保存了很多接口,想要再测试局需要多次修改域名或者端口,这个时候就需要配置环境 1. ...
- fopen在VS中不安全的问题
问题 fopen函数哎VS中使用,报错: error C4996: 'fopen': This function or variable may be unsafe. Consider using f ...
- SqlServer性能检测之Sql语句排查
很多时候,我们在用SQL语句查询数据时,难免会漏掉对SQL语句性能的考虑,所以有时就会造成SqlServer服务占用过高的问题,为了大致排查是哪些SQL语句造成的问题,我们可以通过如下SQL查询出最近 ...
- JMeter的CLI模式(非GUI模式)常用命令
JMeter的CLI模式(非GUI模式)常用命令 Apache JMeter是一款强大的开源性能测试工具,它支持图形用户界面(GUI)模式和非图形用户界面(CLI,即Command Line Inte ...
- flutter-修改Android包名
- 深入集成:使用 DeepSeek SDK for .NET 实现自然语言处理功能
快速上手:DeepSeek SDK for .NET 全面指南 简介 Ater.DeepSeek.AspNetCore 是专门为 .NET 开发者提供的 DeepSeek API SDK.它旨在简化与 ...
- QT5笔记:34. 视口和窗口
 例子: void Widget::paintEvent(QP ...
- 使用Windows系统自带DLL修复工具修复系统缺失dll的问题
1. System File Checker(SFC) System File Checker(SFC)是Windows自带的一个工具,可以扫描系统文件并尝试修复任何受损的文件.要使用SFC,请按照以 ...
- MySQL - [04] 分布式部署&主从复制&读写分离
一.前言 Q1:为什么需要主从复制? 1.在业务复杂的系统中,有一条SQL语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务.使用主从复制,让主库负责写,从库负责读,这样即使主库出现了锁 ...