java volatile进阶(一)
本篇文章继续学习volatile。上篇文章简单的介绍了volatile和synchonized,这篇文章讲一下什么时候可以用volatile。
先看一段代码。
package com.chzhao.voltiletest; public class ChangeValue extends Thread { public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
GlobalValues.STATUS = "stop";
}
}
package com.chzhao.voltiletest; public class VolatileDeep extends Thread { public void run() {
while (true) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (GlobalValues.STATUS.equals("stop")) {
System.out.println(this.getName() + "stop");
GlobalValues.STATUS = "running";
}
}
} public static void main(String[] args) {
Thread t1 = new VolatileDeep();
t1.setName("t1");
t1.start(); Thread t2 = new VolatileDeep();
t2.setName("t2");
t2.start(); Thread t3 = new ChangeValue();
t3.start();
}
}
package com.chzhao.voltiletest; public class GlobalValues {
public static String STATUS = "running";
}
这段代码很简单,输出的是什么呢?
输出的是 t1stop?
还是t2stop?
还是
t1stop
t2stop
?
真实的情况是以上三种都有可能。
因为变量STATUS不是线程安全的,做为一个状态标识,在多线程的情况下状态是不可知的。
但是,如果在变量前面加上volatile关键字。
package com.chzhao.voltiletest; public class GlobalValues {
public volatile static String STATUS = "running";
}
每次的都会输出
t1stop
t2stop
当然,顺序不定。
这说明,如果加了volatile关键字,作为标识状态是能够保证线程安全的。为什么呢?
《Java 理论与实践: 正确使用 Volatile 变量》中介绍:
Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。
《深入理解Java虚拟机:JVM高级特性与最佳实践》中介绍:
当一个变量定义为volatile之后,它将具备两种特性,第一是保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。而普通变量不能做到这一点,普通变量的值在线程间传递均需要通过主内存来完成,例如,线程A修改一个普通变量的值,然后向主内存进行回写,另外一条线程B在线程A回写完成了之后再从主内存进行读取操作,新变量值才会对线程B可见。
关于主内存,以后会有文章介绍。
由上面两段文字可以知道,volatile有一个很好的特性-可见性,可以理解可见性是所有线程均可以立即得到变量的值。所以,在多线程情况下,用volatile修饰状态值是非常适合的。
参考资料:
《Java 理论与实践: 正确使用 Volatile 变量》
《深入理解Java虚拟机:JVM高级特性与最佳实践》
java volatile进阶(一)的更多相关文章
- 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...
- 3.Java异常进阶
3.JAVA异常进阶 1.Run函数中抛出的异常 1.run函数不会抛出异常 2.run函数的异常会交给UncaughtExceptionhandler处理 3.默认的UncaughtExceptio ...
- java volatile的一个验证反例(转)
网上关于java volatile的资料已经不少了,但搜了好久也没看到谁用代码很好地验证过使不使用volatile的差异.最近自己写了个测试,意外的看到了两者的明显区别,为什么说意外呢,因为根据我的测 ...
- Java字符串进阶
Java字符串进阶 前言 最常用的对字符串操作的类有三个,分别是String,StringBuilder,StringBuffer,下面将会详细的说说这三个类...... String String类 ...
- 总结:Java 集合进阶精讲2-ArrayList
知识点:Java 集合框架图 总结:Java 集合进阶精讲1 总结:Java 集合进阶精讲2-ArrayList 初探: ArrayList底层结构是数组,是List接口的 可变数组的实现,所以会占用 ...
- [Java并发编程(五)] Java volatile 的实现原理
[Java并发编程(五)] Java volatile 的实现原理 简介 在多线程并发编程中 synchronized 和 volatile 都扮演着重要的角色,volatile 是轻量级的 sync ...
- [Java并发编程(四)] Java volatile 的理论实践
[Java并发编程(四)] Java volatile 的理论实践 摘要 Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 ...
- [Java并发编程(三)] Java volatile 关键字介绍
[Java并发编程(三)] Java volatile 关键字介绍 摘要 Java volatile 关键字是用来标记 Java 变量,并表示变量 "存储于主内存中" .更准确的说 ...
- 总结:Java 集合进阶精讲1
知识点:Java 集合框架图 总结:Java 集合进阶精讲1 总结:Java 集合进阶精讲2-ArrayList 集合进阶1---为集合指定初始容量 集合在Java编程中使用非常广泛,当容器的量变得非 ...
随机推荐
- MemSQL start[c]up Round 2 - online version(DP)
只有小写字母 那>=2600的直接找单字母串长度大于等于100的就可以了 <2600 的dp找最长回文串 #include <iostream> #include<cst ...
- 【转载】Java中如何写一段内存泄露的程序 & ThreadLocal 介绍和使用
可以参考这段文章: link A1:通过以下步骤可以很容易产生内存泄露(程序代码不能访问到某些对象,但是它们仍然保存在内存中): 上文中提到了使用ThreadLocal造成了内存泄露,但是写的不清不楚 ...
- pinyin4j使用示例
pinyin4j的主页:http://pinyin4j.sourceforge.net/pinyin4j能够根据中文字符获取其对应的拼音,而且拼音的格式可以定制pinyin4j是一个支持将中文转换到拼 ...
- web.xml元素介绍
每一个站的WEB-INF下都有一个web.xml的设定文件,它提供了对我们站台的配置设定.web.xml中定义元素有:◆站台的名称和说明◆针对环境参数(Context)做初始化工作◆Servlet的名 ...
- js array 数组删除元素
/* * 方法:Array.remove(dx) * 功能:根据元素位置值删除数组元素. * 参数:元素值 * 返回:在原数组上修改数组 */ Array.prototype.baoremove = ...
- eclipse集承jboss服务器
eclipse Kepler + Jboss7.1 参考引用文档: http://www.tekdigest.com/how-to-install-jboss-tools-in-eclipse.htm ...
- 【JSP】JSP动态显示时间
function showtime() { var today; var hour; var second; var minute; var year; var month; var date; va ...
- 【MySQL】Java对SQL时间类型的操作(获得当前、昨天、前年。。时间)
Java获得当前时间 java.util.Date date = new java.util.Date(); Timestamp time = new Timestamp(date.getTime() ...
- chrome console js多行输入
一直以来,Chrome控制台都缺少象IE调试台那样的多行执行模式. 今天意外发现Chrome其实也支持多行模式.默认在Chrome控制台上输入回车后会执行该命令,只需要通过输入Shift+Enter ...
- XAMPP for Linux
XAMPP 的 Linux 版图片集锦 安装过程仅 4 个步骤 步骤 1:下载 XAMPP PHP 5.4 XAMPP PHP 5.5 步骤 2:安装 步骤 3:开始运行 步骤 4:测试 使 ...