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. 解决ajax 跨域请求问题

    浏览器console报错: has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is 解决: 服务端加入代 ...

  2. Linux安装nginx详细步骤

    安装依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 在/usr/local/下创建一个nginx的文件夹 ...

  3. Dev TreeList 添加节点图标问题

    1. 在设计界面添加imageCollection控件,在属性页设置图标(可Load from disk,也可从Load from dev gallery) 2. TreeList控件有一个叫做Cus ...

  4. MySQL自动备份shell脚本

    在数据库的日常维护工作中,除了保证业务的正常运行以外,就是要对数据库进行备份,以免造成数据库的丢失,从而给企业带来重大经济损失.通常备份可以按照备份时数据库状态分为热备和冷备,按照备份数据库文件的大小 ...

  5. Python练手例子(7)

    37.对10个数进行排序. 程序分析:可以利用选择法,即从后9个比较过程中,选择一个最小的与第一个元素交换,下次类推,即用第二个元素与后8个进行比较,并进行交换. #python 3.7 if __n ...

  6. 使用 Windows PowerShell 实现 Web UI 自动化 (转)

    转自 https://msdn.microsoft.com/zh-cn/magazine/cc337896.aspx

  7. 现代IM系统中消息推送和存储架构的实现

    现代IM系统中消息推送和存储架构的实现-云栖社区-阿里云 https://yq.aliyun.com/articles/253242

  8. 学习ActiveMQ(二):点对点(队列)模式消息演示

    一:介绍 点对点的消息发送方式主要建立在 消息(Message ),队列(Queue),发送者(Sender),消费者(receiver)上,Queue 存贮消息,Sender 发送消息,receiv ...

  9. Spring boot +mybatis 连接mysql数据库,获取JDBC失败,服务器时区价值”Oйu±e×¼e±¼的识别或代表多个时区

    报出的错误 Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connec ...

  10. gdb调试原理及qemu中的gdbserver

    (一)gdb调试原理 此部分转自:https://blog.csdn.net/u012658346/article/details/51159971     https://www.cnblogs.c ...