volatile变量的主要作用:是使变量在多个线程间可见。

在java中每一个线程都会有一块工作内存区,其中存放着所有线程共享的主内存的变量值的拷贝。当线程执行时,它在自己的工作内存区操作这些变量,为了读取一个共享的变量,一个线程会获取锁定并去清除它的内存工作区,把这些共享变量从所有线程的共享工作区中正确的装入到它自己所在的工作内存区中,当线程解锁时保证该工作内存区中变量的值写回到共享内存中。

volatile的作用就是强制线程到主内存(共享内存)里读取数据,而不去工作线程区里去读取,从而实现了多个线程间变量可见。也就是满足了线程安全的可见性。

当然用synchronized也能实现volatile的功能,但是仅仅为了读写一个或两个实例域就是用synchronized,会让CPU开销很大。

举个栗子:

 public class RunThread extends Thread{

     private volatile boolean isRunning = true;
private void setRunning(boolean isRunning){
this.isRunning = isRunning;
} public void run(){
System.out.println("进入run方法..");
int i = 0;
while(isRunning == true){
//..
}
System.out.println("线程停止");
} public static void main(String[] args) throws InterruptedException {
RunThread rt = new RunThread();
rt.start();
Thread.sleep(1000);
rt.setRunning(false);
System.out.println("isRunning的值已经被设置了false");
} }

在这个栗子中,创建子线程 rt 并启动后,就让主线程休眠 1s,让子线程 rt 运行,因为此时 isRunning为true,所以 rt 子线程会一直循环执行下去。当主线程休眠1s结束,将 isRunning的值改为了false,rt 子线程不在执行循环,rt子线程结束。执行结果为:

volatile虽然拥有多个线程之间的可见性,但是却不具备同步性(即原子性),一般volatile用于只针对多个线程可见的变量操作,并不能代表synchronized的同步操作。

举个栗子:

 package com.song.test;

 public class TestVolatile extends Thread {
public volatile static int n = 0; public static void main(String[] args) {
TestVolatile t1 = new TestVolatile();
t1.start();
for (int i = 0; i < 200000; i++) {
n=n+1;
System.out.println(n);
} } public void run() {
for (int i = 0; i < 200000; i++) {
n=n+1;
System.out.println(n);
}
}
}

volatile 验证非原子性操作的栗子

在这个例子中,让 n 通过主线程和子线程分别加了两回,每次加了20000,如果是原子性操作那么n最终的值应该是400000,但实际上它的值是399998,因为它是非原子性的:

结果为:

那怎么用volatile关键字呢。对volatile修饰的变量要所有筛选:

变量的读写操作是独立的,不依赖其当前值(如 n=n+1),也不依赖于其他状态状态变量的共同参与与不变约束。

java线程学习之volatile关键字的更多相关文章

  1. java 线程Thread 技术--volatile关键字

    java 语言中允许线程访问共享变量,为了保证共享变量能被准确和一致的更新,Java 语言提供了volatile 关键字,也就是我们所说的内存一致性: 问题抛出:(尝试去运行下面代码,以及将volat ...

  2. java线程学习之synchronized关键字

    关键字synchronized的作用是实现线程间的同步.它的任务是对同步的代码加锁.一个代码块同时只能有同一个线程进行读和写操作,从而保证线程间是安全的. 线程安全的概念是:当多个线程访问某一个类(对 ...

  3. Java并发编程学习:volatile关键字解析

    转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...

  4. Java并发编程:volatile关键字解析(学习总结-海子)

    博文地址:Java并发编程:volatile关键字解析

  5. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  6. 【转】Java并发编程:volatile关键字解析

    转自:http://www.importnew.com/18126.html#comment-487304 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备 ...

  7. (转)Java并发编程:volatile关键字解析

    转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...

  8. 《转》JAVA并发编程:volatile关键字解析

    volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...

  9. Java并发编程:volatile 关键字

    转自:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 其实Java语言是支持多线程的,为了解决线程并发的问题,在语言内部 ...

随机推荐

  1. Web版记账本开发记录(一)代码和功能展示

    一丶基本机构 数据库截图 record表 年份表 index.jsp <%@ page language="java" contentType="text/html ...

  2. CentOS7 Nginx安装及配置反向代理

    背景: Mono (Mono JIT compiler version 5.4.0.201 ) jexus-5.8.2-x64(<CentOS7 安装 jexus-5.8.2-x64>) ...

  3. 微信小程序wx.showLoading

    效果图: 代码: wx.showLoading({ title: '加载中...', }) wx.request({ url: '', success(res){}, fail(){}, comple ...

  4. Linux学习笔记(三)

    昨天将计算机概论部分算是看完了,然后我又将后面的内容过了一遍,因为我本身对Linux有一些了解,所以就跳到这文件权限与目录管理配置这章了,话不多说,开始做笔记. Linux文件权限与目录配置 群组 所 ...

  5. html中的列表

    无序列表(什么前面默认一个实心的黑原点) <ul> <li>什么</li> <li>什么</li> <li>什么</li& ...

  6. 如何将两个PDF文件合并到一个页面中

    在目前职场办公中,很多使用的文件格式是PDF文件格式,由于工作的需要,经常需要将PDF文件合并在一起,但由于PDF文件不能直接编辑修改,不能OFFICE,WPS那样,通过复制粘贴将两者合并,那如何解决 ...

  7. 深入理解iostat

    前言 iostat算是比较重要的查看块设备运行状态的工具,相信大多数使用Linux的同学都用过这个工具,或者听说过这个工具.但是对于这个工具,引起的误解也是最多的,大多数人对这个工具处于朦朦胧胧的状态 ...

  8. 【Python全栈-JavaScript】jQuery事件

    jQuery事件 一.页面载入 当DOM载入就绪可以查询及操纵时绑定一个要执行的函数. 这是事件模块中最重要的一个函数,因为它可以极大地提高web应用程序的响应速度. 简单地说,这个方法纯粹是对向 w ...

  9. JVM入门到放弃之基本概念

    1. 基本概念 jvm 是可运行Java代码的假想计算机,包括一套字节码指令集.一组寄存器.一个栈.一个垃圾回收堆和一个存储方法域. jvm 是运行在操作系统之上的,屏蔽了与具体操作系统平台相关的信息 ...

  10. pytorch加载预训练模型参数的方式

    1.直接使用默认程序里的下载方式,往往比较慢: 2.通过修改源代码,使得模型加载已经下载好的参数,修改地方如下: 通过查找自己代码里所调用网络的类,使用pycharm自带的函数查找功能(ctrl+鼠标 ...