用 volatile 修饰的变量可以保证线程的“可见性”,也就是,任何线程修改了这个 volatile 修饰的值都会通知其他线程来主缓存中重新读取值。

下面通过例子加以说明:

public class VolatileTest {
// 对比有无 volatile 关键字的区别
volatile boolean running = true; public void m(){
System.out.println("start run");
while (running){
}
System.out.println("end run");
} public static void main(String[] args) {
VolatileTest volatileTest = new VolatileTest();
new Thread(volatileTest::m, "t1").start();
try {
//主线程睡眠一秒钟,目的是保证t1获得cpu执行权
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
volatileTest.running = false;
}
} 有volatile的情况下,程序会输出:
start run
end run
无volatile的情况下,程序会输出:
start run

出现这种情况的原因跟java的内存模型(JMM)有关,每个线程运行都有自己独立的一份内存,用于保存线程的局部变量,线程修改一个全局变量要经过三个过程:

i. 拷贝主内存的变量到线程内存。

ii. 修改拷贝的变量值。

iii. 把修改的值写回主内存。

由于线程修改一个公共变量需要这三个步骤,可见这个修改不具备“原子性”,这也就是volatile和synchronized的不同之处,volatile不能取代synchronized来使用。

如下面例子所示:

public class VolatleAndSynchornized {
public volatile int count = 0; // public synchronized void incre(){
public void incre(){
for (int i = 0; i < 10000; i ++){
count ++;
}
} public static void main(String[] args) {
VolatleAndSynchornized obj = new VolatleAndSynchornized();
obj.process();
System.out.println(obj.count);
} public void process() {
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 5; i ++) {
try {
Runner t = new Runner();
threads.add(t);
} catch (Exception e) {
e.printStackTrace();
}
} threads.forEach(Thread::start); threads.forEach(thread -> {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
} public class Runner extends Thread {
@Override
public void run() {
incre();
}
}
} 用volatile的话输出:(每次运行结果不见得相同)
24236
而用synchronized的话输出:
50000

理解volatile与synchronized的更多相关文章

  1. volatile和synchronized到底啥区别?多图文讲解告诉你

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...

  2. java学习:JMM(java memory model)、volatile、synchronized、AtomicXXX理解

    一.JMM(java memory model)内存模型 从网上淘来二张图: 上面这张图说的是,在多核CPU的系统中,每个核CPU自带高速缓存,然后计算机主板上也有一块内存-称为主内(即:内存条).工 ...

  3. 理解volatile

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  4. 剑指Offer——线程同步volatile与synchronized详解

    (转)Java面试--线程同步volatile与synchronized详解 0. 前言 面试时很可能遇到这样一个问题:使用volatile修饰int型变量i,多个线程同时进行i++操作,这样可以实现 ...

  5. Java并发专题(三)深入理解volatile关键字

    前言 上一章节简单介绍了线程安全以及最基础的保证线程安全的方法,建议大家手敲代码去体会.这一章会提到volatile关键字,虽然看起来很简单,但是想彻底搞清楚需要具备JMM.CPU缓存模型的知识.不要 ...

  6. java多线程中 volatile与synchronized的区别-阿里面试

    volatile 与 synchronized 的比较(阿里面试官问的问题) ①volatile轻量级,只能修饰变量.synchronized重量级,还可修饰方法 ②volatile只能保证数据的可见 ...

  7. volatile和synchronized实现内存可见性的区别

    先看看synchronized实现内存可见性 加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另外一个重要的方面:内存可见性.我们不仅希望防止某个线程正在使用对象状态而另一个 ...

  8. volatile和synchronized的区别

    volatile和synchronized特点 首先需要理解线程安全的两个方面:执行控制和内存可见. 执行控制的目的是控制代码执行(顺序)及是否可以并发执行. 内存可见控制的是线程执行结果在内存中对其 ...

  9. JAVA多线程之volatile 与 synchronized 的比较

    一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...

随机推荐

  1. 显示器分辨率不同,部分winform控件在其他机器上显示不全

    在开发机器上效果如下: 而到其他电脑上效果如下: 解决办法: 将窗体的AutoScaleMode属性设置为None,尝试一下,应该可以了. 关于AutoScaleMode的属性,可以参考 http:/ ...

  2. BZOJ1563: [NOI2009]诗人小G(决策单调性 前缀和 dp)

    题意 题目链接 Sol 很显然的一个dp方程 \(f_i = min(f_j + (sum_i - sum_j - 1 - L)^P)\) 其中\(sum_i = \sum_{j = 1}^i len ...

  3. CSS选择器备忘录

    CSS选择器备忘录 基本选择器 Selector Meaning Example 通用选择器 匹配任何元素 * 标签选择器 CSS1中称之为元素选择器,匹配为指定标签的所有元素 div 伪元素选择器 ...

  4. [SVN]TortoiseSVN工具培训4─客户端常用操作命令

    1.权限认证 当进行SVN任何操作时,如果是首次操作,SVN会弹出权限认证. 输入用户名和密码点击确认即可完成认证. 勾选保存用户数据信息,可以避免将来重复输入用户名和密码认证. 2.删除权限认证信息 ...

  5. 开源时序服务器influxdb使用

    文档 https://influxdb.com/docs/v0.9/introduction/overview.html 配置文件 /etc/opt/influxdb/influxdb.conf re ...

  6. python3线程介绍01(如何启动和调用线程)

    #!/usr/bin/env python# -*- coding:utf-8 -*- import osimport time,randomimport threading # 1-进程说明# 进程 ...

  7. LoadRunner性能测试之常见函数及参数的说明和作用

       

  8. TP5.0: 显示错误信息

    在TP5中,我们运行的代码有错误无法执行时,只显示页面错误,而不显示错误信息 对我我来讲是无法接受滴!!毕竟我还是个小渣渣,查看了百度,解决方案是: 在application/config,php中找 ...

  9. Poj(1521),哈夫曼编码

    题目链接:http://poj.org/problem?id=1521 这里,网上有很多博客都有写,很多人没有建树,直接就是求一下这个哈夫曼编码的长度,的确很巧妙,我也用的这个方法,但是,几乎所有博客 ...

  10. 计算最大矩形面积,POJ(2082)

    题目链接:http://poj.org/problem?id=2082 把矩形按照高度一次递增的循序排列,当违反这一规则的时候,更新ans,用新的data替换之前的矩形.然后最后扫一遍. #inclu ...