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的更多相关文章

  1. 【转】java中volatile关键字的含义

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

  2. Java中Volatile关键字详解

    一.基本概念 先补充一下概念:Java并发中的可见性与原子性 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值, ...

  3. 转:java中volatile关键字的含义

    转:java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  4. Java中Volatile的作用

    Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...

  5. java中volatile不能保证线程安全

    今天打了打代码研究了一下java的volatile关键字到底能不能保证线程安全,经过实践,volatile是不能保证线程安全的,它只是保证了数据的可见性,不会再缓存,每个线程都是从主存中读到的数据,而 ...

  6. java中volatile

    volatile用来修饰变量.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volat ...

  7. Java并发-volatile的原理及用法

    Java并发-volatile的原理及用法 volatile属性:可见性.保证有序性.不保证原子性.一.volatile可见性 在Java的内存中所有的变量都存在主内存中,每个线程有单独CPU缓存内存 ...

  8. java中volatile关键字的理解

    一.基本概念 Java 内存模型中的可见性.原子性和有序性.可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有 ...

  9. java 使用volatile实现线程数据的共享

    java 使用volatile实现线程数据的共享 直接上代码看效果: public class VolatileTest extends Thread { private volatile boole ...

  10. java 并发——volatile

    java 并发--volatile 介绍 维基百科: volatile 是一个类型修饰符(type specifier).volatile 的作用是确保本条指令不会因编译器的优化而省略,且要求每次直接 ...

随机推荐

  1. Node.js 几个重启工程的工具

    pm2, forever, nodemon, supervisor 均可在 npm 查找相关资料和用法. 线上工程推荐 pm2 开发推荐 supervisor

  2. mac 下 git log 退出方法

    英文状态下按 Q (大小写无论)即可.

  3. Min_25筛初级应用:求$[1,n]$内质数个数

    代码 #include <bits/stdc++.h> #define rin(i,a,b) for(int i=(a);i<=(b);++i) #define irin(i,a,b ...

  4. 利用 clipboardData 在网页中实现截屏粘贴的功能

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  5. HBase 集群监控系统构建

    HBase 集群监控系统构建 标签(空格分隔): Hbase 一, 集群为什么需要监控系统 总的来说是为了保证系统的稳定性,可靠性,可运维性.具体来说我认为有以下几点: 掌控集群的核心性能指标,了解集 ...

  6. kubernetes配置dashborad,web界面

    一,将kubernetes-dashboard.yaml-1.10和admin-rbac.yaml和token.sh的上传到k8s的计算机上 .如图 二,切入到这三个文件所在的目录下,执行命令:kub ...

  7. React Native商城项目实战07 - 设置“More”界面导航条

    1.More/More.js /** * 更多 */ import React, { Component } from 'react'; import { AppRegistry, StyleShee ...

  8. WPF 自定义按钮 Style

    <Style TargetType="{x:Type Button}" x:Key="DefaultButton"> <Setter Prop ...

  9. Octavia health-manager 与 amphora 故障修复的实现与分析

    目录 文章目录 目录 Health Manager 监控 amphora 健康状态 故障转移 故障迁移测试 Health Manager Health Manager - This subcompon ...

  10. C#SQL小结

    对于c#获取Sql数据目前我采用的是 System.Data.SqlClient.SqlDataReader类. 主要用到如下API: SqlDataReader.Read():每次获取一行的数据,直 ...