今天被人问到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++,会被编译成以下三步:

      1. 获取num的值;
      2. 执行num+1;
      3. 将结果赋值给num。

  volatile关键字只能保证可见性,并不能保证原子性。

结论:
  volatile关键字只能保证这3步在编译后指令不会被重新排序,并不能保证多个线程并发的数据安全。建议在方法上加上synchronized修饰或配合其他Lock锁使用。

												

volatile修饰全局变量,可以保证线程并发安全吗?的更多相关文章

  1. volatile修饰全局变量,可以保证并发安全吗?

    今天被人问到volatile能不能保证并发安全? 呵,这能难倒我? 上代码: //电脑太好,100线程起步~public class ThreadTest { private static volat ...

  2. 两个线程并发执行以下代码,假设a是全局变量,那么以下输出______是不可能的?

    3.两个线程并发执行以下代码,假设a是全局变量,那么以下输出______是不可能的? void foo(){    ++a;    printf("%d ",a);}A.3 2   ...

  3. 【Java并发编程】6、volatile关键字解析&内存模型&并发编程中三概念

    volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...

  4. volatile关键字解析&内存模型&并发编程中三概念

    原文链接: http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java5之前,它是一个 ...

  5. volatile关键字的详解-并发编程的体现

    xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!! 参 ...

  6. 除了Synchronized关键字还有什么可以保证线程安全?

    除了Synchronized关键字还有什么可以保证线程安全?     日常使用Java开发时,多线程开发,一般就用Synchronized保证线程安全,防止并发出现的错误和异常,那么 除了Synchr ...

  7. java--加强之 Java5的线程并发库

    转载请申明出处:http://blog.csdn.net/xmxkf/article/details/9945499 01. 传统线程技术回顾 创建线程的两种传统方式: 1.在Thread子类覆盖的r ...

  8. volatile是否就是原子性/线程同步的

    在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...

  9. Java多线程(四) —— 线程并发库之Atomic

    一.从原子操作开始 从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作,因此首先从这里开始). 很多情况下 ...

  10. java中volatile关键字的含义--volatile并不能做到线程安全

    在Java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...

随机推荐

  1. 在linux系统通过OpenSSL工具自签https证书

    工具介绍 OpenSSL是SSL/TLS协议的实现工具 key是私钥文件,用于对发送给客户端的数据加密,以及对从客户端接收的数据进行解密. csr是证书签名请求文件,用于提交给证书颁发机构(CA)对证 ...

  2. bat脚本(批处理程序)调用WinRAR及7zip压缩和解压缩

    最近项目要用到定期批量将文件及文件夹下的文档打包,所以想到要写脚本来实现,然后做Windows定期任务调用.bat脚本(批处理程序)调用WinRAR及7zip压缩和解压缩. 调用WinRAR来实现 因 ...

  3. [Java] Solon 框架的三大核心组件之一插件扩展体系

    1.Solon 的三大核心组件 核心组件 说明 Plugin 插件扩展机制 提供"编码风格"的扩展体系 Ioc/Aop 应用容器 提供基于注入依赖的自动装配体系 Context+H ...

  4. SOUI4新版本的日志系统介绍

    原来的日志输出宏用法有点奇怪,感觉总是不够理想.这近有点时间终于把它重整了一下. 以前的用法就不介绍了,重点介绍一下新版本的用法. 在SOUI中使用的日志系统包含两个部分:日志输出宏及日志到文件的打印 ...

  5. 解读 DeepSeek-R1 论文 - 通俗易懂版

    引言:让 AI 学会"思考"的新突破 在近年来的人工智能浪潮中,大型语言模型(LLM)如 ChatGPT 已经能回答各种问题,但它们在复杂推理方面仍有不足.所谓复杂推理,比如解决奥 ...

  6. 拒绝繁忙!免费使用 deepseek-r1:671B 参数满血模型

    相信大家都已经有体验过deepseek-r1的强大推理能力,由于其网页版本免费使用的原因,用户量激增.同时据传还遭受了大量的网络攻击,这使得过程不是很流程,经常收到类似下图的问题: 同时,API服务也 ...

  7. 记一次CUDA报错

    报错内容:CUDA error: device-side assert triggered 原因:使用ResNet50训练时使用了pretrained=True的模型,但实际类别数classes远超过 ...

  8. ABB机器人IO板DSQC651维修检查方法

    ABB机器人作为工业自动化的重要设备,其稳定性和可靠性对于生产线的持续运行至关重要.然而,在实际使用中,由于各种原因,可能会出现ABB机器人IO板DSQC651故障,影响机器人的正常运行. 一.ABB ...

  9. JUC并发—9.并发安全集合二

    大纲 1.并发安全的数组列表CopyOnWriteArrayList 2.并发安全的链表队列ConcurrentLinkedQueue 3.并发编程中的阻塞队列概述 4.JUC的各种阻塞队列介绍 5. ...

  10. JUC并发—10.锁优化与锁故障

    大纲 1.标志位修改场景优先使用volatile(服务优雅停机) 2.数值递增场景优先使用Atomic类(心跳计数器) 3.共享变量仅对当前线程可见的场景优先使用ThreadLocal(edits l ...