Java 多线程 -- volatile 山寨版的synchronized
在 多线程中,每个线程会把数据从主内存中拷贝到自己的工作内存中,当线程完成计算后,再把工作内存的数据更新到主内存中,或者当主内存主数据有更新是,线程会去主内存取最新数据。但是,当线程特别忙时,就不会去主内存读最新数据了。
在 java 的多线程中 volatile 主要是为了保证数据的可见性同步,是一个轻量级的synchronized,但是 volatile 并不能保证数据的原子性。
下面看一下加了volatile 和没有加 volatile的区别:
不加volatile:
public class VolatileTest {
	private  static int num = 0;
	public static void main(String[] args) throws InterruptedException {
		new Thread(()->{
			while(num == 0) {
				if(num == 1) {
					System.out.println("num=" + num);
					break;
				}
			}
		}).start();
		Thread.sleep(1000);
		num = 1;
	}
}
运行以上代码:

由于 while 循环 是一个比较底层的代码,所以一秒后,循环并没有结束。
下面给变量加上volatile 关键字测试:
public class VolatileTest {
	private volatile static int num = 0;
	public static void main(String[] args) throws InterruptedException {
		new Thread(()->{
			while(num == 0) {
				if(num == 1) {
					System.out.println("num=" + num);
					break;
				}
			}
		}).start();
		Thread.sleep(1000);
		num = 1;
	}
}
再运行代码:

运行代码1s 后可以看到循环结束。
Java 多线程 -- volatile 山寨版的synchronized的更多相关文章
- java多线程之内存可见性-synchronized、volatile
		
1.JMM:Java Memory Model(Java内存模型) 关于synchronized的两条规定: 1.线程解锁前,必须把共享变量的最新值刷新到主内存中 2.线程加锁时,将清空工作内存中共享 ...
 - java多线程(3)---synchronized、Lock
		
synchronized.Lock 一.概述 1.出现线程不安全的原因是什么? 如果我们创建的多个线程,存在着共享数据,那么就有可能出现线程的安全问题:当其中一个线程操作共享数据时,还未操作完成,另外 ...
 - [Java多线程] volatile 关键字正确使用方法
		
volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性,即多线程环境中,使用 volatile 关键字的变量仅可以保证不同线程读取变量时,可以读到最新修改的变量值,但是 ...
 - Java多线程的同步机制(synchronized)
		
一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个 ...
 - java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决
		
0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...
 - Java多线程volatile和synchronized总结
		
volatile是轻量级的synchronized,在多处理器(多线程)开发中保证了共享变量的"可见性".可见性表示当一个线程修改了一个共享变量时,另外一个线程能读到这个修改的值. ...
 - Java 多线程(二)synchronized和volatile
		
脏读: 脏读指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据.总的来说取到的数据是其实是被更改过的,但还没有保存到数 ...
 - Java多线程总结之由synchronized说开去(转)
		
这几天不断添加新内容,给个大概的提纲吧,方面朋友们阅读,各部分是用分割线隔开了的: synchronized与wait()/notify() JMM与synchronized ThreadLocal与 ...
 - java多线程-----volatile
		
谈谈Java中的volatile 内存可见性 留意复合类操作 解决num++操作的原子性问题 禁止指令重排序 总结 内存可见性 volatile是Java提供的一种轻量级的同步机制,在并发编程中, ...
 
随机推荐
- 【NLP面试QA】基本策略
			
目录 防止过拟合的方法 什么是梯度消失和梯度爆炸?如何解决? 在深度学习中,网络层数增多会伴随哪些问题,怎么解决? 关于模型参数 模型参数初始化的方法 模型参数初始化为 0.过大.过小会怎样? 为什么 ...
 - iOS MachO
			
一.前言 1.1 程序和进程 广义上的程序就是一个静态的可执行文件,是由一个已经编译好的指令和数据集合的一个文件.就像通过 Xcode 编译好的 Mach-O 文件.而进程则是一个动态的概念,是程序的 ...
 - [noip模拟]改造二叉树<LIS>
			
1.改造二叉树 [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随 ...
 - [codevs2597]团伙<并查集>
			
题目描述 Description 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的朋友是我的朋友: 我敌人的敌人也是我的朋友 ...
 - 关于C#三层架构增删改查中的“添加”问题
			
关于“添加”功能的实现比较简单: 先来一个简单的界面: 然后是代码: ··采用的是三层架构的思想写的·· 在DAO中的方法为: (使用了动软自动生成代码) 希望对您有所帮助!
 - 使用错误代码对象进行C++错误处理
			
原文发表于codeproject,由本人翻译整理分享于此. 前言 我已经使用了本文描述的代码和机制近20年了,到目前为止,我还没有找到更好的方法来处理大型C++项目中的错误.最初的想法是从一篇文章(D ...
 - 3NF的无损连接和保持函数依赖的分解、BCNF的无损连接的分解
			
首先,需要了解3NF.BCNF范式的要求. 3NF:不存在非主属性对码的传递函数依赖或部分函数依赖. 如AB-C,A->C 码为(A,B),A,B是主属性,C是非主属性,C部分函数依赖于码,即 ...
 - Java进行二元操作类型转换
			
当对两个数值进行二元操作时,先要将两个操作数转换为同一种类型,然后再进行计算. 如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型. 否则,如果其中一个操作数是float ...
 - JDBCUtils,根据当前MySQL数据库下面的表生成java实体类
			
自己简单写的JDBCUtils,可以根据当前数据库下面的表生成java实体类,代码萌新,请多多包涵. 初始化配置: //驱动程序名//不固定,根据驱动 static String driver = & ...
 - 【数据库】MySQL数据库(二)
			
一.数据库文件的导出 1.在DOS命令行下导出数据库(带数据) mysqldump -u root -p 数据库名 > E:\wamp\www\lamp175\lamp175.sql 2.在DO ...