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的更多相关文章

  1. volatile关键字 学习记录1

    虽然已经工作了半年了...虽然一直是在做web开发....但是平时一直很少使用多线程..... 然后最近一直在看相关知识..所以就有了这篇文章 用例子来说明问题吧 public class Volat ...

  2. volatile关键字学习

    volatile关键字在实际工作中我用的比较少,可能因为我并不是造轮子的.但是用的少不是你不掌握的借口,还是要创造场景去使用这个关键字,本文将会提供丰富的demo. volatile 发音:英[ˈvɒ ...

  3. C++——volatile关键字的学习

    首先声明一点,本文是关于volatile关键字的学习,学习内容主要是来自一些大牛的网络博客. 一篇是何登成先生的C/C++ Volatile关键词深度剖析(http://hedengcheng.com ...

  4. JAVA多线程基础学习三:volatile关键字

    Java的volatile关键字在JDK源码中经常出现,但是对它的认识只是停留在共享变量上,今天来谈谈volatile关键字. volatile,从字面上说是易变的.不稳定的,事实上,也确实如此,这个 ...

  5. Java多线程学习(三)volatile关键字

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  6. JAVA多线程学习- 三:volatile关键字

    Java的volatile关键字在JDK源码中经常出现,但是对它的认识只是停留在共享变量上,今天来谈谈volatile关键字. volatile,从字面上说是易变的.不稳定的,事实上,也确实如此,这个 ...

  7. Thread 学习记录 <1> -- volatile和synchronized

    恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1;  ...

  8. Java并发编程学习笔记 深入理解volatile关键字的作用

    引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的 ...

  9. C语言学习及应用笔记之四:C语言volatile关键字及其使用

    在C语言中,还有一个并不经常使用但却非常有用的关键字volatile.那么使用volatile关键字究竟能干什么呢?接下来我将就此问题进行讨论. 一个使用volatile关键字定义变量,其实就是告诉编 ...

随机推荐

  1. kettle中参数和变量的区别

    图一: 图二: 何时使用'?'何事使用${}应当根据情况: 在图二中使用的是${}因为此时没有"作为参数的字段",所以只能用el表达式直接获取其值,在图一中有"作为参数的 ...

  2. [No0000A4]DOS命令(cmd)批处理:替换字符串、截取字符串、扩充字符串、获取字符串长度

    1.替换字符串,即将某一字符串中的特定字符或字符串替换为给定的字符串.举例说明其功能:========================================= @echo off set a ...

  3. Linux下更换默认yum源为网易yum源的操作记录

    废话不多说,下面记录了centos下更换系统默认yum源为网易yum源的操作过程:1)备份原有的默认yum源[root@bastion-IDC ~]# cp /etc/yum.repos.d/Cent ...

  4. 通过配置Mysql参数提高写入速度

    1) innodb_buffer_pool_size 如果用Innodb,那么这是一个重要变量.相对于MyISAM来说,Innodb对于buffer size更敏感.MySIAM可能对于大数据量使用默 ...

  5. 解读ASP.NET 5 & MVC6系列(17):MVC中的其他新特性

    (GlobalImport全局导入功能) 默认新建立的MVC程序中,在Views目录下,新增加了一个_GlobalImport.cshtml文件和_ViewStart.cshtml平级,该文件的功能类 ...

  6. [LeetCode] Wiggle Subsequence 摆动子序列

    A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...

  7. [LeetCode] Wildcard Matching 外卡匹配

    Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. ...

  8. [LeetCode] Letter Combinations of a Phone Number 电话号码的字母组合

    Given a digit string, return all possible letter combinations that the number could represent. A map ...

  9. [LeetCode] 3Sum Closest 最近三数之和

    Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...

  10. Underscore 整体架构浅析

    前言 终于,楼主的「Underscore 源码解读系列」underscore-analysis 即将进入尾声,关注下 timeline 会发现楼主最近加快了解读速度.十一月,多事之秋,最近好多事情搞的 ...