java中volatile的简单理解
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/7833881.html
据说,volatile是java语言中最轻量级的并发控制方式。
volatile可以保证变量的可见性,指的是什么呢?
可见性指的是在某一线程中对变量进行修改之后,其他线程可以立即发现并使用这个修改(一个线程的修改对其他线程可见)。
可见性的实现方式:volatile对java内存模型中主内存和工作内存交互方式的控制。volatile确保一个线程对其修饰的变量的更改立即写入到主内存,同时确保每一次针对其修饰变量的读取操作直接从主内存中获取(即volatile强制将assign赋值操作和store、write操作绑定在一起,将use使用操作强制和read、load操作绑定在一起,这样assign之后必须执行store、write操作,use操作之前必须先执行read、load操作)这样就确保了其他线程读取到的变量的值是最新的(不熟悉这几个操作的同学请先了解java内存模型)。
注意:volatile可以实现可见性,但是无法实现原子操作。原子操作是与java代码相关的,并不是这么一个关键字既可以控制得了的。(请将可见性和原子操作区分开来,我之前就混淆在一起,分开之后立即通透了)
java中实现原子操作的方式还是有很多的,但是并不包含volatile,简单的实现方式有:atomic包下的原子操作(通过CAS实现),基本数据类型的读写操作等。
java中经典的非原子操作如自增实现,普通的i++操作看似只有一句话,但是编译成机器指令之后拥有多少行,不可知,坑顶不是一句就能实现的,这么多命令要执行当然无法保证原子性,这时候我们可以AtomicInteger和AtomicLong原子操作类的getAndIncrement()方法来实现。
volatile的另一个作用就是避免重排序,使用内存屏障的方式来实现禁止重排序。在单线程环境中当然没有必要禁止重排序,但是在多线程环境中重排序后执行的代码就可能会出错,比如线程A中需要检测线程B中的某一个变量的值,如果没有使用volatile修饰该变量,线程B中针对这个变量的操作就可能会发生重排序,可能会提前执行,这是一旦操作执行,那么线程A就可以会提前得到这个变量的值(或许是在一些线程A的准备工作还未全部准备好的情况,假设这些准备工作在线程B中定义,但是与变量操作无依赖关系,一旦变量操作提前,这些准备工作就会滞后,这是线程A就会在准备工作尚未完成的情况下启动执行后行代码,导致出错)。为变量加上volatile修饰之后,就会禁止其操作的重排序,保证所以的准备工作全部执行完成之后在进行变量操作,然后线程A在准备齐备的情况启动,得以正常执行。
java中volatile的简单理解的更多相关文章
- java中volatile关键字的理解
一.基本概念 Java 内存模型中的可见性.原子性和有序性.可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有 ...
- java中的二进制运算简单理解
package test9; public class StreamTest { public static void main(String[] args) { int a = 15;// 0b11 ...
- java中线程同步的理解(非常通俗易懂)
转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...
- Java中Volatile的作用
Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...
- Java中线程同步的理解 - 其实应该叫做Java线程排队
Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...
- 【转】java中volatile关键字的含义
java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...
- Java中Volatile关键字详解
一.基本概念 先补充一下概念:Java并发中的可见性与原子性 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值, ...
- 转:java中volatile关键字的含义
转:java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...
- 多线程(三) java中线程的简单使用
java中,启动线程通常是通过Thread或其子类通过调用start()方法启动. 常见使用线程有两种:实现Runnable接口和继承Thread.而继承Thread亦或使用TimerTask其底层依 ...
随机推荐
- util包里的一些类的使用
好几天没有更新我的博客了 .国庆放假出去玩了一趟,这回来应该收心回到我的事业上了,哈哈哈!废话不多说,开始学习吧!首先今天来学习一些例子,这些例子可以回顾假期遗忘的知识,还能提高自己的能力.程序也会相 ...
- 聊聊Java语言中的单例
package com.xinke.mybatis.test; public class TestSingleton { private static TestSingleton ts = null; ...
- 【转】TCP/IP报文格式
1.IP报文格式 IP协议是TCP/IP协议族中最为核心的协议.它提供不可靠.无连接的服务,也即依赖其他层的协议进行差错控制.在局域网环境,IP协议往往被封装在以太网帧(见本章1.3节)中传送.而所有 ...
- vue + ajax + php 接口的使用小接
vue + ajax + php 接口的使用小接 前端代码: (获取用户信息,并渲染页面) userinfor.html <!DOCTYPE html> <html lang=&qu ...
- LinearGradientBrush,RadialGradientBrush的样式说明
LinearGradientBrush 使用线性渐变绘制区域.线性渐变沿直线定义渐变.该直线的终点由线性渐变的 StartPoint 和 EndPoint 属性定义.LinearGradientBru ...
- 传统 HTML 表单数据的“整存整取”
在日常开发中,涉及表单的处理司空见惯.过往,在取值和赋值的过程中,借助 jQuery 常常只是逐个控件进行操作,可惜这样开发效率并不高.那么能不能批量获取整个表单的值呢,以及批量为表单赋值. 一.取值 ...
- 为UWP应用开启回环访问权限
最近在项目中遇到UWP调用WCF的需求,考虑到UWP不能寄宿WCF服务(如果能,或者有类似技术,请告知),于是写了一个WPF程序寄宿WCF服务,然后再用UWP调用服务. 写的时候并没有碰到什么问题,直 ...
- 张高兴的 Windows 10 IoT 开发笔记:HC-SR04 超声波测距模块
HC-SR04 采用 IO 触发测距.下面介绍一下其在 Windows 10 IoT Core 环境下的用法. 项目运行在 Raspberry Pi 2/3 上,使用 C# 进行编码. 1. 准备 H ...
- 【读书笔记】《写给大忙人看的Java SE 8》——Java8新特性总结
虽然看过一些Java 8新特性的资料,但是平时很少用到,时间长了就忘了,正好借着Java 9的发布,来总结下一些Java 8中的新特性. 接口中的默认方法和静态方法 先考虑一个问题,如何向Java中的 ...
- GET 和 POST 比较整理
差异 上传文件只能使用 POST GET 传输数据有大小限制 GET 传输的数据类型不灵活:GET是使用url来传输数据,那么比如空格字符以及类似&这样的字符就不方便传输.(当然可以使用发送前 ...