volatile关键字 学习记录2
public class VolatileTest2 implements Runnable{
volatile int resource = 0;
public static void main(String[] args) {
VolatileTest2 vt = new VolatileTest2();
new Thread(vt).start();
new Thread(vt).start();
while(Thread.activeCount() > 1){
Thread.yield();
}
System.out.println(vt.resource);
}
@Override
public void run() {
for(int i=0; i<100000000; i++){
resource++;
}
}
}
这个例子中虽然resource前面有volatile关键字,但是运行结果有时候仍然不是200000000..为什么呢? 我想分享下我的观点.
首先每个线程有自己的内存,他们修改resource的时候会先把数据拷贝到自己的内存中,再修改,再写回主内存..所以如果是这样的话那么多个线程同时操作可能会有很多种情况,下面举2种情况
(不加volatile关键字的时候会出现的N种情况中的2种)
第一种情况:

第二种情况

上面2种情况都会使t2线程把resource写回主内存的时候把t1自增那次操作覆盖掉.因为t1与t2线程读主内存的resource的值是一样的...所以相当于t1的自增是无效的.
当resource前面加了volatile关键字的时候:
用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最新的值。
http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
所以加了这个关键字以后是可以避免第二种情况的.
t1 resource自增以后会直接写回主内存,使t2读取操作读取到的是最新的值.相当于resource++与写回主内存是同一个事务,不可以分隔.
但是仍然不能避免第一种情况的发生.
在第一种情况下,线程t2 读取resource是发生在t1 resource自增之前的,所以当t1 自增以后并不会影响t2线程内存中的resource,因为这并不违背volatile.如果此时t2再去读取resource那才是最新的值.不过可惜他在t1自增之前就读取了,所以t2中resource的值仍然是旧的.当t2写回主内存的时候仍然会覆盖t1自增的值.
以上就是我的理解.
volatile关键字 学习记录2的更多相关文章
- volatile关键字 学习记录1
虽然已经工作了半年了...虽然一直是在做web开发....但是平时一直很少使用多线程..... 然后最近一直在看相关知识..所以就有了这篇文章 用例子来说明问题吧 public class Volat ...
- volatile关键字学习
volatile关键字在实际工作中我用的比较少,可能因为我并不是造轮子的.但是用的少不是你不掌握的借口,还是要创造场景去使用这个关键字,本文将会提供丰富的demo. volatile 发音:英[ˈvɒ ...
- C++——volatile关键字的学习
首先声明一点,本文是关于volatile关键字的学习,学习内容主要是来自一些大牛的网络博客. 一篇是何登成先生的C/C++ Volatile关键词深度剖析(http://hedengcheng.com ...
- JAVA多线程基础学习三:volatile关键字
Java的volatile关键字在JDK源码中经常出现,但是对它的认识只是停留在共享变量上,今天来谈谈volatile关键字. volatile,从字面上说是易变的.不稳定的,事实上,也确实如此,这个 ...
- Java多线程学习(三)volatile关键字
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- JAVA多线程学习- 三:volatile关键字
Java的volatile关键字在JDK源码中经常出现,但是对它的认识只是停留在共享变量上,今天来谈谈volatile关键字. volatile,从字面上说是易变的.不稳定的,事实上,也确实如此,这个 ...
- Thread 学习记录 <1> -- volatile和synchronized
恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1; ...
- Java并发编程学习笔记 深入理解volatile关键字的作用
引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的 ...
- C语言学习及应用笔记之四:C语言volatile关键字及其使用
在C语言中,还有一个并不经常使用但却非常有用的关键字volatile.那么使用volatile关键字究竟能干什么呢?接下来我将就此问题进行讨论. 一个使用volatile关键字定义变量,其实就是告诉编 ...
随机推荐
- Oracle update和order by
今天遇到一个关于SQL转换成Oracle语句的问题,描述如下: select * from emp order by deptno; select * from dept; Sql Server: u ...
- 15天玩转redis —— 第十篇 对快照模式的深入分析
我们知道redis是带有持久化这个能力了,那到底持久化成到哪里,持久化成啥样呢???这篇我们一起来寻求答案. 一:快照模式 或许在用Redis之初的时候,就听说过redis有两种持久化模式,第一种是S ...
- Oracle学习笔记十一 游标
游标的简介 游标的概念 游标是从数据表中提取出来的数据,以临时表的形式存放在内存中,在游标中有一个数据指针,在初始状态下指向的是首记录,利用fetch语句可以移动该指针,从而对游标中的数据进行各种操作 ...
- 封装系统(以封装Windows 7为例)
安装步骤: 1.安装系统 2.启用Administrator帐户 3.进行简单的系统设置 4.系统精简 5.安装Adobe Flash Player 6.设置IE主页 7.在系统盘(C盘)创建Sysp ...
- LDR、STR指令
LDR(load register)指令将内存内容加载入通用寄存器 STR(store register)指令将寄存器内容存入内存空间中 #define GPJ0CON 0xE0200240 _sta ...
- Web Service
Web Service全称XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术.是:通过SOAP ...
- 前端之JavaScript基础
前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C ...
- Openjudge 1.13-23:区间内的真素数(每日一水)
总时间限制: 1000ms 内存限制: 65536kB 描述 找出正整数 M 和 N 之间(N 不小于 M)的所有真素数.真素数的定义:如果一个正整数 P 为素数,且其反序也为素数,那么 P 就为 ...
- [LeetCode] Reverse Vowels of a String 翻转字符串中的元音字母
Write a function that takes a string as input and reverse only the vowels of a string. Example 1:Giv ...
- asp.net获取服务器绝对路径和相对路径
绝对路径 AppDomain.CurrentDomain.SetupInformation.ApplicationBase 相对路径 Server.MapPath("~/")表示当 ...