- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java并发编程之Volatile变量详解分析由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
Volatile关键字是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量, 相比synchronized(synchronized通常称为重量级锁),volatile更轻量级,因为它不会引起线程上下文的切换和调度。 但是volatile 变量的同步性较差(有时它更简单并且开销更低),而且其使用也更容易出错.
来看一段代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public
class
Test {
public
static
void
main(String[] args) {
WangZai wangZai =
new
WangZai();
wangZai.start();
for
(; ;){
if
(wangZai.isFlag()){
System.out.println(
"hello"
);
}
}
}
static
class
WangZai
extends
Thread {
private
boolean
flag =
false
;
public
boolean
isFlag(){
return
flag;
}
@Override
public
void
run() {
try
{
Thread.sleep(
1000
);
}
catch
(InterruptedException e) {
e.printStackTrace();
}
flag =
true
;
System.out.println(
"flag = "
+ flag);
}
}
}
|
你会发现,永远都不会输出hello这一段代码,按道理线程改了flag变量,主线程也能访问到的呀?
但是将flag变量用volatile修饰一下,就能输出hello这段代码 。
1
|
private
volatile
boolean
flag =
false
;
|
每个线程操作数据的时候会把数据从主内存读取到自己的工作内存,如果他操作了数据并且写会了,那其他已经读取的线程的变量副本就会失效了,需要对数据进行操作又要再次去主内存中读取了.
volatile保证不同线程对共享变量操作的可见性,也就是说一个线程修改了volatile修饰的变量,当修改写回主内存时,另外一个线程立即看到最新的值.
重排序需要遵守一定规则:
什么是重排序?
为了提高性能,编译器和处理器常常会对既定的代码执行顺序进行指令重排序.
重排序的类型有哪些呢?
一个好的内存模型实际上会放松对处理器和编译器规则的束缚,也就是说软件技术和硬件技术都为同一个目标,而进行奋斗:在不改变程序执行结果的前提下,尽可能提高执行效率.
JMM对底层尽量减少约束,使其能够发挥自身优势.
因此,在执行程序时,为了提高性能,编译器和处理器常常会对指令进行重排序.
一般重排序可以分为如下三种:
那 Volatile 是怎么保证不会被执行重排序的呢?
java编译器会在生成指令系列时在适当的位置会插入内存屏障指令来禁止特定类型的处理器重排序.
为了实现volatile的内存语义,JMM会限制特定类型的编译器和处理器重排序,JMM会针对编译器制定volatile重排序规则表:
是否能重排序第二个操作第一个操作普通读/写volatile读volatile写普通读/写NOvolatile读NONONOvolatile写NONO 。
举例来说,第三行最后一个单元格的意思是:在程序顺序中,当第一个操作为普通变量的读或写时,如果第二个操作为volatile写,则编译器不能重排序这两个操作.
从上表我们可以看出:
需要注意的是:volatile写是在前面和后面分别插入内存屏障,而volatile读操作是在后面插入两个内存屏障.
写 。
读 。
从JDK5开始,提出了happens-before的概念,通过这个概念来阐述操作之间的内存可见性.
happens-before 关系的定义:
看到这儿,你是不是觉得,这个怎么和 as-if-serial 语义一样呢。没错, happens-before 关系本质上和 as-if-serial 语义是一回事.
as-if-serial 语义保证的是单线程内重排序之后的执行结果和程序代码本身应该出现的结果是一致的, 。
happens-before 关系保证的是正确同步的多线程程序的执行结果不会被重排序改变.
一句话来总结就是:如果操作 A happens-before 操作 B ,那么操作 A 在内存上所做的操作对操作 B 都是可见的,不管它们在不在一个线程.
在 Java 中,对于 happens-before 关系,有以下规定:
到此这篇关于Java并发编程之Volatile变量详解分析的文章就介绍到这了,更多相关Java Volatile变量内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/weixin_60707895/article/details/121013097 。
最后此篇关于Java并发编程之Volatile变量详解分析的文章就讲到这里了,如果你想了解更多关于Java并发编程之Volatile变量详解分析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: How to nest OR statements in JavaScript? 有没有办法做到这一点:
在 JavaScript 中有没有办法让一个变量总是等于一个变量?喜欢var1 = var2但是当var2更新,也是var1 . 例子 var var1 = document.getElementBy
我正在努力理解这代表什么 var1 = var2 == var3 我的猜测是这等同于: if (var2 == var3): var1 = var2 最佳答案 赋值 var1 = var2
这个问题已经有答案了: What does the PHP error message "Notice: Use of undefined constant" mean? (2 个回答) 已关闭 8
我在临时表中有几条记录,我想从每条记录中获取一个值并将其添加到一个变量中,例如 color | caption -------------------------------- re
如何将字符串转为变量(字符串变量--> $variable)? 或者用逗号分隔的变量列表然后转换为实际变量。 我有 2 个文件: 列名文件 行文件 我需要根据字符串匹配行文件中的整行,并根据列名文件命
我有一个我无法解决的基本 php 问题,我也想了解为什么! $upperValueCB = 10; $passNodeMatrixSource = 'CB'; $topValue= '$uppe
这可能吗? php $variable = $variable1 || $variable2? 如果 $variable1 为空则使用 $variable2 是否存在类似的东西? 最佳答案 PHP 5
在 Perl 5.20 中,for 循环似乎能够修改模块作用域的变量,但不能修改父作用域中的词法变量。 #!/usr/bin/env perl use strict; use warnings; ou
为什么这不起作用: var variable; variable = variable.concat(variable2); $('#lunk').append(variable) 我无法弄清楚这一点
根据我的理解,在32位机器上,指针的sizeof是32位(4字节),而在64位机器上,它是8字节。无论它们指向什么数据类型,它们都有固定的大小。我的计算机在 64 位上运行,但是当我打印包含 * 的大
例如: int a = 10; a += 1.5; 这运行得很完美,但是 a = a+1.5; 此作业表示类型不匹配:无法从 double 转换为 int。所以我的问题是:+= 运算符 和= 运算符
您好,我写了这个 MySQL 存储过程,但我一直收到这个语法错误 #1064 - You have an error in your SQL syntax; check the manual that
我试图在我的场景中显示特定的奖牌,这取决于你的高分是基于关卡的目标。 // Get Medal Colour if levelHighscore goalScore { sc
我必须维护相当古老的 Visual C++ 源代码的大型代码库。我发现代码如下: bIsOk = !!m_ptr->isOpen(some Parameters) bIsOk的数据类型是bool,is
我有一个从 MySQL 数据库中提取的动态产品列表。在 list 上有一个立即联系 按钮,我正在使用一个 jquery Modal 脚本,它会弹出一个表单。 我的问题是尝试将产品信息变量传递给该弹出窗
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
jQuery Core Style Guidelines建议两种不同的方法来检查变量是否已定义。 全局变量:typeof variable === "undefined" 局部变量:variable
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: “Variable” Variables in Javascript? 我想肯定有一种方法可以在 JavaScrip
在语句中使用多重赋值有什么优点或缺点吗?在简单的例子中 var1 = var2 = true; 赋值是从右到左的(我相信 C# 中的所有赋值都是如此,而且可能是 Java,尽管我没有检查后者)。但是,
我是一名优秀的程序员,十分优秀!