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 的作用是确保本条指令不会因编译器的优化而省略,且要求每次直接 ...
随机推荐
- [CF1093G]Multidimensional Queries:线段树
分析 非常有趣的一道题. 式子中的绝对值很难处理,但是我们发现: \[\sum_{i=1}^{k}|a_{x,i}-a_{y,i}|=\sum_{i=1}^{k}max(a_{x,i}-a_{y,i} ...
- uiautomatorviewer报错 Error taking device screenshot: EOF
报以下错误 估计是端口冲突 解决方法: 1. netstat -ano | findstr 5037 查看占用5037端口的进程 2. taskkill /pid 10508 /f 杀掉此进程 3 ...
- Centos 7 Redmine 安装,粘贴图片插件安装
转自: https://blog.csdn.net/jctian000/article/details/80591878 Redmine 是一个开源的.基于Web的项目管理和缺陷跟踪工具.它用日历和甘 ...
- Python 使用Qt进行开发(二)
上次简单实现了显示窗口,下面我们在窗口中加入一些部件. 1,我们在窗口中使用 setToolTip() 方法添加一个文本提示,在窗口中鼠标暂停几秒即可显示该文本信息. class test(): de ...
- Mybaits成长之路
今天刚开始接触mybaits,接下来介绍mybaits的demo的建立 1根据数据库表定义一个实体类Employee package com.atguigu.mybatis.bean; public ...
- 将项目发布到neuxs私服
需要在 pom.xml中配置 <distributionManagement> <repository> <id>user-release</id> & ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_3 完成account的一对一操作-通过写account的子类方式查询
先把多表查询的sql语句写出来 想要显示的字段 创建一个AccountUser类 继承Account.这样它就会从父类上继承一些信息 这里只需要定义username和address就可以了 .然后生成 ...
- div动画旋转效果
animation: spin 10s linear infinite;
- LoadRunner11安装及破解
一.LoadRunner11安装 以管理员身份运行setup.exe 选择第一个LoadRunner完整安装程序 按照界面会弹出以上提示框,直接选择否 检查系统缺少哪些组件,点击“确定”自动安装 点击 ...
- 吴恩达机器学习(二) 单变量线性回归(Linear Regression with one variable)
一.模型表示 1.一些术语 如下图,房价预测.训练集给出了房屋面积和价格,下面介绍一些术语: x:输入变量或输入特征(input variable/features). y:输出变量或目标变量(out ...