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语言是支持多线程的,为了解决线程并发的问题,在语 ...
随机推荐
- biancheng-Redis教程
目录http://c.biancheng.net/redis/ 1Redis是什么2Windows下载安装Redis3Ubuntu下载安装Redis4Redis配置文件5Redis数据类型6Redis ...
- C# WebAPI 插件热插拔
背景 WebAPI 插件热插拔是指在不重启应用程序的情况下,能够动态地加载.更新或卸载功能模块(即插件)的能力.这种设计模式在软件开发中非常有用,尤其是在需要频繁更新或扩展功能的大型系统中.通过实现插 ...
- 两个半成品的ORM
只要是有点结构化的思想,不可能项目里一个sqlHelper 满天飞 到处写 ,最终你的c#代码还是得返回一个Class 才好操作,sqlhelper, datatable这种东西也只是临时将就一下,稍 ...
- 我来告诉你怎么在macOS上畅玩金铲铲之战
天选福星,灵蛇献瑞,<金铲铲之战>"天选福星"赛季好运上线!请接收这份来自<金铲铲之战>的新春邀约--"天选福星"正式回归,羁绊焕新升级 ...
- python 爬取博客访问量
一.代码 """ Version: Python3.5 Author: OniOn Site: http://www.cnblogs.com/TM0831/ Time: ...
- HTML骨架简述
<!DOCTYPE html><!-- <!声明 DOC docment文件/文档 TYPE 类别/类型 告知浏览器当前文档为html> --><html&g ...
- Python - [04] 面试题汇总
题记部分 001 || Python的特点和优点 Python可以作为编程的入门语言,因为他具有以下特质: (1)解释型 (2)动态特性 (3)面向对象 (4)语法简洁 (5)开源 (6)丰富的社区资 ...
- SpringMVC - 谈谈你对SpringMVC的理解
谈谈你对 Spring MVC 的理解? 普通人:Spring MVC 它是一个MVC框架吧,就是,我们可以使用Spring MVC来开发Web应用...呃 它是基于Servlet上的一个扩展,就是它 ...
- docker下安装Harbor
安装docker-compose # 安装docker-compose curl -L https://github.com/docker/compose/releases/download/1.18 ...
- FastAPI路由与请求处理全解:手把手打造用户管理系统 🔌
title: FastAPI路由与请求处理全解:手把手打造用户管理系统 date: 2025/3/2 updated: 2025/3/2 author: cmdragon excerpt: 通过咖啡店 ...