Java Volatile 修饰 a++ 分析

Java+之+volatile+详解 Volatile可以看做是轻量级的 Synchronized,它只保证了共享变量的可见性。在线程 A 修改被 volatile 修饰的共享变量之后,线程 B 能够读取到正确的值。java 在多线程中操作共享变量的过程中,会存在指令重排序与共享变量工作内存缓存的问题。 阅读详情

一、Java并发编程三大特性

1、原子性

原子性是指:所要执行的代码块不可被分割,不会因并发操作而出现交叉的现象。

如果(A1、B1、C1)和(A2、B2、C2)分别是线程1和线程2的原子操作代码块,多线程执行的一种结果是(A1、B1、C1)->(A2、B2、C2);
如果A1、B1、C1分别是线程1的三个原子操作代码块,A2、B2、C2分别是线程2的三个原子操作代码块,多线程执行的一种结果是A1、B2、C1、A2、C2、B1(Ax、Bx、Cx顺序不一致是因为可能出现的指令重排,这是编译器所做的一种优化操作),从中还可以看出,多线程的操作出现了交叉执行的情况。

// 假设现在三个操作指令,A、B、和C
// 原子操作时
class Thread_1{
	{A1; B1; C1;}
}
class Thread_2 {
	{A2; B2; C2;}
}
/* 执行结果1:(A1、B1、C1)->(A2、B2、C2) */

// 非原子操作时
class Thread_1{
	A1;
	B1;
	C1;
}
class Thread_2 {
	A2;
	B2;
	C2;
}
/* 执行结果2:A1、B2、C1、A2、C2、B1(Ax、Bx、Cx顺序不一致是因为可能出现的指令重排),同时,多线程的操作出现了交叉执行的情况 */

2、可见性

可见性是指:一个线程对共享变量修改后,其他线程会立即得知该修改。
Java内存模型将内存分为主内存(共享变量存储的位置)和工作内存(线程对主内存内容的复制)。可见性保证了一个线程修改某个变量后,立即将修改后的内容同步回主内存,其他线程读取该共享变量的时候,需要重新到主内存中拷贝该修改后的变量(先行发生原则)。
在这里插入图片描述

3、有序性

有序性是指:在本线程内观察,所有操作都是有序的。在一个线程观察另一个线程,所有操作都是无序的,无序是因为发生了指令重排序。
在 Java 内存模型中,允许编译器和处理器对指令进行重排序,重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。
volatile 关键字通过添加内存屏障的方式来禁止指令重排,即重排序时不能把后面的指令放到内存屏障之前。
也可以通过 synchronized 来保证有序性,它保证每个时刻只有一个线程执行同步代码,相当于是让线程顺序执行同步代码。

二、Volatile 修饰 a++

1、volatile问题分析

如上所述,volatile可以保证可见性,但是无法保证原子性。
volatile修饰的变量a做++操作时,实际的指令包括三个(得到a的值,a+1,将a+1赋值给a),因此可能会出现多个线程交叉执行的结果。

2、解决方案

I) 使用synchronize修饰a++代码块,

// 修饰的变量为a
synchronize(Object) {
	a++;
}
/* 执行结果:a的值为a+1后的新值 */

II) 使用锁Lock

// 使用ReentrantLock
ReentrantLock reentrantLock = new ReentrantLock();
private volatile a = 0;

public void addA() {
	// 上锁
	reentrantLock.lock();
	try {
		a++;
	} finally {
		// 保证锁的释放
		reentrantLock.unlock();
	}
}
/* 执行结果:a的值为a+1后的新值 */

III) 使用JUC包下的原子类AtomicInteger

private AtomicInteger a= new AtomicInteger();

public void add() {
    a.incrementAndGet();
}

三、参考

1.https://www.cnblogs.com/kexianting/p/8566318.html
2.https://blog.youkuaiyun.com/zhaxiaodong/article/details/78834674
3.https://blog.youkuaiyun.com/fu123123fu/article/details/79794017

为什么 volatile 不能保证 i++ 的原子性?但对 long 和 double 却是例外? 大家好,我是你们的技术小伙伴小米!今天我们来聊一个 Java 社招面试中经常被问到的问题:volatile 能使得一个非原子操作变成原子操作吗?这道题看似简单,实际上却暗藏玄机。如果你觉得 volatile 仅仅是“保证可见性”,那这次你可能要涨涨姿势了!阿康最近在准备 Java 高级开发的社招面试,今天他来到了一家互联网大厂,和面试官聊得还不错。然而,到了关键时刻,面试官微微一笑,丢出了这样一个问题:“volatile 关键字能让一个非原子操作变成原子操作吗?”阿康心里想:“volatile 不是保证可见 阅读详情

相关推荐

Java进阶:volatile使用详解

概述 volatile是java提供的轻量级的同步机制,保证了可见性,不保证原子性。 了解volatile工作机制,首先要对Java内存模型(JMM)有初步的认识: 每个线程创建时,JVM会为其创建一份私有的工作内存(栈空间),不同线程的工作内存之间不能直接互相访问 JMM规定所有的变量都存在主内存,主内存是共享内存区域,所有线程都可以访问 线程对变量进行读写,会从主内存拷贝一份副本到自己的工作内存,操作完毕后刷新到主内存。所以,线程间的通信要通过主内存来实现。 volatile的作用是:线程对副本变量进

qq_28834355的博客 4306

java 为何volatile无法解决a++原子性问题的终极理解!

 首先我们来解释为什么会有可见性问题:简单来说就是每个线程都含有各自的多层缓存,共享一个主内存。对变量的操作是在工作内存中完成的,所以各个线程不清楚其他线程的具体操作,也就会出现可见性问题。  java内存模型(java memory model)将下图的L1 cache、L2 cache等视为工作内存,而L3 cache、RAM视为主内存。注意这里的registers(寄存器),它是完成具体变量操作的地方。  所以大家就记住总归有三个存储数据的地方:寄存器,工作内存和主内存。其中寄存器和工作内存为线程私

weixin_43614115的博客 1180

重带电粒子的能量歧离(energy straggling)

能量歧离,Bethe-Bloch

G751888629的博客 2298

谈谈volatile作用与a++的原子性问题

一.了解volatile工作原理 volatile在工作时涉及到三个储存部分分别是主内存,高速缓存,以及寄存器。 这三者的读取数据关系为: 假设现在变量a 被volatile关键字修饰 且初始值为1 此时进行修改值的操作 a=a+1; 对于一个线程来说 他将操作的步骤为 取值 [a=1] ----- 计算[a+1] ---- 存值[a=2] 操作完存值的步骤后,立即将其他线程中的高速缓存,也就是工作内存设为失效,当其他线程要对变量a进行操作的时候 取到的值 便是来自于主内存。 由上图可知要对一个值

Hxuening的博客 470

癌症免疫治疗预测神器TIDE:从原理到实战(避坑指南)

本文详细解析了癌症免疫治疗预测工具TIDE的核心原理及实战应用。TIDE算法通过模拟肿瘤免疫逃逸的两种核心机制(T细胞功能障碍和排除),为临床决策提供精准预测。文章涵盖数据准备、标准化流程、网页工具操作指南及结果解读,帮助科研人员和临床医生避开常见误区,优化免疫治疗策略。

weixin_29309475的博客 199

抖音直播间人气接口算法 抖音协议

抖音直播间人气接口算法 抖音协议 抖音算法

Q44804487的博客 1万+

Java内存模型及Java关键字 volatile的作用和使用说明

先来看看这个关键字是什么意思:volatile [ˈvɒlətaɪl] adj. 易变的,不稳定的; 从翻译上来看,volatile表示这个关键字是极易发生改变的。volatile是java语言中,最轻量级的并发同步机制。这个关键字有如下两个作用:1、任何对volatile变量的修改,java中的其他线程都可以感知到2、volatile会禁止指令冲排序优化  在详细讲解volatile关键字之前...

weixin_30323631的博客 153

时空数据建模的跨节点联邦图神经网络:KDD21 Cross-Node Federated Graph Neural Network for Spatio-Temporal Data Modeling

前言 联邦学习(FL)虽然已经被广泛研究,但是对复杂的时空依赖关系进行建模以提高预测能力仍然是一个开放的问题。此外目前最优的时空预测模型假定对数据的访问不受限制,忽略了对数据共享的限制。基于此,本文提了一个基于图联邦学习的时空数据模型 Cross-Node Federated Graph Neural Network (CNFGNN),该模型在跨节点联邦学习的约束下,使用基于图神经网络(GNN)的架构对底层图结构进行编码,属于结构化联邦的一种,每个本地模型利用私有数据进行学习,并保持分散性。CNFGNN

qq_56027260的博客 1810

volatile 指令重排以及为什么禁止指令重排

这里是引用 java指令重排以及volatile 为什么禁止指令重排指令重排序什么是指令重排序为什么要进行指令重排序如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 指令重排序 什么是指令重排序 处理器对写入的代码进行乱序执行优化, 并保证 优化后的执行 结果和正常执.

weixin_43982927的博客 5273

远程桌面项目

远程桌面项目

weixin_41560737的博客 1934

华为OD机试 新系统 双机位C卷 往年真题 机考题库(持续收录中)以及算法考点详解(Python/JS/C/C++)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释发现新题目,随时更新。

学Java,找哪吒 5万+

volatile关键字修饰对象是什么效果?

如果volatile的修饰的是一个引用类型的对象变量,那么对象中定义的一些普通全局变量是否会受到volatile关键字的效果影响呢?” 接下来,我们就一起来分析下这个问题!让我们先通过一个例子来回顾下volatile关键字的作用! public class VolatitleFoo { //类变量 final static int max = 5; static int ...

1939

S7-1200PLC V90伺服绝对值编码器校准功能块

S7-1200PLC通过111报文和EPOS模式实现位置轴轴控功能(FB284封装)-优快云博客文章浏览阅读173次。EASY_SINA_POS的详细使用介绍请参考下面文章链接:S7-1200PLC使用标准报文111和EPOS模式实现V90 PN总线伺服定位(Easy_SINA_Pos)_西门子sinapos-优快云博客文章浏览阅读132次。文章浏览阅读7k次。先简单说下如何获取FB284,一般有2种方法,Startdrive软件可以操作大部分西门子的驱动器,建议安装调试方便,缺点就是软件太大。

RXXW_Dor的博客 968

volatile不具有原子性的理解之解读i++疑惑

volatile修饰的变量变化过程: 第一:使用volatile关键字会强制将修改的值立即写入主存; 第二:使用volatile关键字的话,当线程2进行修改时,会导致线程1的工作内存中缓存变量的缓存行无效; 第三:由于线程1的工作内存中缓存变量的缓存行无效,所以线程1再次读取变量的值时会去主存读取。 可见性和原子性: 可见性:对一个volatile变量的读,总是能看到(任意线程)对这个vo...

越努力越幸运 2244

SAP 经营范围(Operating Concern) 和业务范围 (Business Area) 在核算架构或是管理架构中的区别和联系分别是什么 请给具体的示例

摘要:SAP系统中,业务范围(Business Area)和经营范围(Operating Concern)在核算架构中具有不同功能。业务范围是FI/CO共用维度,用于跨公司码的业务线核算(如电子产品、机械设备),支持内部管理和简单对外报表。经营范围则是CO-PA专属维度,聚焦获利能力分析,可细化到产品+客户+区域组合(如分析手机在华东区域的获利情况)。两者存在层级关联:经营范围包含业务范围作为基础维度,业务范围数据会传递至经营范围进行深度分析。实际应用中需先配置业务范围,再设置经营范围并关联相关维度,共同支

金牌架构师 96

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java中Volatile 修饰符

Java中Volatile 修饰符 上次我们说到为什么会多卖一张票出去,其实是因为在多线程的情况下 如果不同步 那么 线程与线程之间不是不具有可见性的。 下面是摘自 http://www.cnblogs.com/zhengbin/p/5654805.html 郑州文武对 可见性 和原子性的理解 可见性:   可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉。通常,我们无法...

u012045045的博客 705

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

volatile关键字i++操作为何失效

public class Test { public volatile int inc = 0; public void increase() { inc++; } public static void main(String[] args) { final Test test = new Test(); ...

weixin_41259597的博客 1978

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Java volatile修饰符的用法及作用详解版

要深刻理解volatile这个关键字的用法及作用,需要补充以下知识: 1、 内存访问操作/指令执行操作的乱序:假设每个CPU都分别运行着一个会触发内存访问操作的程序。那么对于这样一个CPU,其内存访问顺序是非常松散的,在保证程序上下文逻辑关系的前提下,CPU可以按它所喜欢的顺序来执行内存操作。类似地,编译器也可以将它输出的指令安排成任何它喜欢的顺序,只要保证不影响程序...

Saintyyu的博客 2652

volatile修饰

参考网址:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html       参考代码:https://github.com/xiangqian19831224/atomic.git synchronized  同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized

liuxiangqian的专栏 452

volatile修饰变量java_volatile 关键字(修饰变量)

volatile 关键字(修饰变量)1. 含义是一种比 sychronized 关键字更轻量级的同步机制,访问 volitile 变量时,不会执行加锁操作。2. 作用volatile 是一个类型修饰符(type specifier)。volatile 的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。保证可见性禁止指令重排序优化指令重排序优化:普通的变量仅仅会保证在...

weixin_33609654的博客 557

Java的volatile修饰符

Java的volatile修饰符是和多线程编程相关的,被volatile修饰的变量当其状态被某一个线程修改是,其状态被其他线程可见。volatile变量不会缓存在寄存器或者其他处理器不可见的地方。下面通过一个示例来说明。class Test implements Runnable { static volatile boolean flag = true; @Override

半夏。的博客 538

i++ 或 ++i 是原子操作吗?

前面写了一篇文章,讨论了i++和++i的区别(https://blog.youkuaiyun.com/lijianqingfeng/article/details/103474225)。该文的前提都是不存在并发的情况,通过i++ 和++i编译后的代码分析其执行效果。 public class Test { private static volatile int count = 0; pu...

lijianqingfeng的专栏 3314

volatile 关键字(修饰变量)

文章目录1. 含义2. 作用3. 如何保证可见性4. 如何禁止指令重排序优化5. volatile 是不安全的6. volatile 不适用场景 1. 含义 是一种比 sychronized 关键字更轻量级的同步机制,访问 volatile 变量时,不会执行加锁操作。 2. 作用 volatile 是一个类型修饰符(type specifier)。volatile 的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。 保证可见性 禁止指令重排序优化 指令重排序优化:普通的

程序员小羊的博客 1452

volatile修饰的变量_不是吧,volatile 底层原理你都还不知道?

概念1 volatile变量,用来确保将变量的更新操作通知到其他线程。2 当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。3 volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。特性假如一个共享变量(类的成员变量、类的静态成员变量)被vola...

weixin_39853968的博客 461

volatile i++

https://blog.youkuaiyun.com/dm_vincent/article/details/79604716 一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。 禁止进行指令重排序。 关于可见性,先看一段代码,假如线程1先执行...

1652

volatile修饰符的作用详解

volatile修饰的共享变量,具有以下两个特点: 保证了不同线程对该变量操作的内存可见性 有序性(禁止指令重排序) 要更详细的理解volatile修饰符的作用,就要理解java内存模型,如果已经理解请跳过此段话,不然推荐看这里:https://blog.youkuaiyun.com/xianyun1992/article/details/107723694 可见性: 当一个变量被volatile修饰时,那么对它的修改会立刻刷新到主存,当其它线程需要使用该变量时,会去内存中读取新值。而普通变量则不能保证这一点。

我还可以 768
上一篇: 字节跳动2019春招后端开发工程师-笔试题解析
下一篇: CentOS7安装及配置Nginx
gd_2014
博客等级 码龄12年 1粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值