Java的volatile
1、同步
同synchronized相比(synchronized通常称为重量级锁),volatile更轻量级
如图,如果变量没有volatile关键字,那么A线程对该变量的改变存储在内存A,B变量不可知。

将一个共享变量声明为volatile后,会有以下效应:
1.当写一个volatile变量时,JMM会把该线程对应的本地内存中的变量强制刷新到主内存中去;
2.这个写会操作会导致其他线程中的缓存无效。
非原子操作出现的问题:
package test; import java.util.concurrent.CountDownLatch; /**
* Created by chengxiao on 2017/3/18.
*/
public class Counter {
public static volatile int num = 0;
//使用CountDownLatch来等待计算线程执行完
static CountDownLatch countDownLatch = new CountDownLatch(30);
public static void main(String []args) throws InterruptedException {
//开启30个线程进行累加操作
for(int i=0;i<30;i++){
new Thread(){
public void run(){
for(int j=0;j<10000;j++){
num++;//自加操作
}
countDownLatch.countDown();
}
}.start();
}
//等待计算线程执行完
countDownLatch.await();
System.out.println(num);
}
}
得到的结果并不是300000,而是224291,原因是num++不是个原子性的操作,而是个复合操作(读取、加1、赋值)。所以,在多线程环境下,有可能线程A将num读取到本地内存中,此时其他线程可能已经将num增大了很多,线程A依然对过期的num进行自加,重新写到主存中。
解决方法:通过使用Automic原子操作类
/**
* Created by chengxiao on 2017/3/18.
*/
public class Counter {
//使用原子操作类
public static AtomicInteger num = new AtomicInteger(0);
//使用CountDownLatch来等待计算线程执行完
static CountDownLatch countDownLatch = new CountDownLatch(30);
public static void main(String []args) throws InterruptedException {
//开启30个线程进行累加操作
for(int i=0;i<30;i++){
new Thread(){
public void run(){
for(int j=0;j<10000;j++){
num.incrementAndGet();//原子性的num++,通过循环CAS方式
}
countDownLatch.countDown();
}
}.start();
}
//等待计算线程执行完
countDownLatch.await();
System.out.println(num);
}
}
2、禁止指令重排序优化
重排序在多线程中可能存在的问题:
public class TestVolatile {
int a = 1;
boolean status = false;
/**
* 状态切换为true
*/
public void changeStatus(){
a = 2;//
status = true;//
}
/**
* 若状态为true,则running。
*/
public void run(){
if(status){//
int b = a+1;//
System.out.println(b);
}
}
}
上述第1、2步由于不存在依赖关系,可能会被系统冲排序,从而不能保证第四步的b=3。
Java的volatile的更多相关文章
- 【转】java中volatile关键字的含义
java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...
- Java中Volatile关键字详解
一.基本概念 先补充一下概念:Java并发中的可见性与原子性 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值, ...
- 转:java中volatile关键字的含义
转:java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...
- Java中Volatile的作用
Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...
- java中volatile不能保证线程安全
今天打了打代码研究了一下java的volatile关键字到底能不能保证线程安全,经过实践,volatile是不能保证线程安全的,它只是保证了数据的可见性,不会再缓存,每个线程都是从主存中读到的数据,而 ...
- java中volatile
volatile用来修饰变量.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volat ...
- Java并发-volatile的原理及用法
Java并发-volatile的原理及用法 volatile属性:可见性.保证有序性.不保证原子性.一.volatile可见性 在Java的内存中所有的变量都存在主内存中,每个线程有单独CPU缓存内存 ...
- java中volatile关键字的理解
一.基本概念 Java 内存模型中的可见性.原子性和有序性.可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有 ...
- java 使用volatile实现线程数据的共享
java 使用volatile实现线程数据的共享 直接上代码看效果: public class VolatileTest extends Thread { private volatile boole ...
- java 并发——volatile
java 并发--volatile 介绍 维基百科: volatile 是一个类型修饰符(type specifier).volatile 的作用是确保本条指令不会因编译器的优化而省略,且要求每次直接 ...
随机推荐
- 激活navicat premium12
按Win键和R键打开运行并输入cmd并回车或Win10 开始菜单右键,打开命令提示符或者命令提示符(管理员) ,建议使用命令提示符(管理员) 最为稳妥. 1.首先使用cd命令切换到当前Navicat ...
- python中加入中文注释报错处理
python中加入中文注释,运行报错如下 解决方法: 在py文件的第一行加入 #coding:utf-8 即可
- [LeetCode]-010-Regular_Expression_Matching
Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...
- ES6 字符串的解构赋值
字符串也可以解构赋值.这是因为此时,字符串被转换成了一个类似数组的对象. const [a, b, c, d, e] = 'hello'; a // "h" b // " ...
- 本地运行aws lambda credential 配置 (missing credential config error)
参照这篇文章 http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-sha ...
- 关于R语言中set.seed()
在r中取sample时候,经常会有set.seed(某数),经常看见取值很大,其实这里无论括号里取值是多少,想要上下两次取值一样,都需要在每次取值前输入同样的set.seed(某数),才能保证两次取值 ...
- leetcode-mid-backtracking-17. Letter Combinations of a Phone Number
mycode 68.26% class Solution(object): def letterCombinations(self, digits): """ :typ ...
- sklearn—LinearRegression,Ridge,RidgeCV,Lasso线性回归模型简单使用
线性回归 import sklearnfrom sklearn.linear_model import LinearRegression X= [[0, 0], [1, 2], [2, 4]] y = ...
- A 内存挂 B 封包挂 C 钩子挂 D CALL挂 外挂
https://www.zhihu.com/question/32291769 作者:猎狐链接:https://www.zhihu.com/question/32291769/answer/70929 ...
- Windows环境下Mysql 5.7读写分离简单记录
一.目的 本文记录了在Windows环境中,mysql数据库读写分离配置过程. 二.准备: Master机器:Windows 10 虚拟机,IP:192.168.3.32 Slave机器:Window ...