JAVA 并发实现六(Volatile的使用)
Java™ 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。
这两种机制的提出都是为了实现代码线程的安全性。其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错。
在JDK1.2之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。
要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:
- 对变量的写操作不依赖于当前值。
- 该变量没有包含在具有其他变量的不变式中。
package com.subject01;
public class VolatileDemo extends Object implements Runnable {
//value变量没有被标记为volatile
private int value;
//missedIt变量被标记为volatile
private volatile boolean missedIt;
//creationTime不需要声明为volatile,因为代码执行中它没有发生变化
private long creationTime;
public VolatileDemo() {
value = 10;
missedIt = false;
//获取当前时间,亦即调用Volatile构造函数时的时间
creationTime = System.currentTimeMillis();
}
public void run() {
print("entering run()");
//循环检查value的值是否不同
while ( value < 20 ) {
//如果missedIt的值被修改为true,则通过break退出循环
if ( missedIt ) {
//进入同步代码块前,将value的值赋给currValue
int currValue = value;
//在一个任意对象上执行同步语句,目的是为了让该线程在进入和离开同步代码块时,
//将该线程中的所有变量的私有拷贝与共享内存中的原始值进行比较,
//从而发现没有用volatile标记的变量所发生的变化
Object lock = new Object();
synchronized ( lock ) {
//不做任何事
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//离开同步代码块后,将此时value的值赋给valueAfterSync
int valueAfterSync = value;
print("in run() - see value=" + currValue +", but rumor has it that it changed!");
print("in run() - valueAfterSync=" + valueAfterSync);
break;
}
}
print("leaving run()");
}
public void workMethod() throws InterruptedException {
print("entering workMethod()");
print("in workMethod() - about to sleep for 2 seconds");
Thread.sleep(2000);
//仅在此改变missedIt的值
missedIt = true;
print("in workMethod() - just set missedIt=" + missedIt);
print("in workMethod() - about to sleep for 3 seconds");
// Thread.sleep(5000);
//仅在此改变value的值
value = 50;
print("in workMethod() - just set value=" + value);
print("in workMethod() - about to sleep for 5 seconds");
Thread.sleep(3000);
print("leaving workMethod()");
}
/*
*该方法的功能是在要打印的msg信息前打印出程序执行到此所化去的时间,以及打印msg的代码所在的线程
*/
private void print(String msg) {
//使用java.text包的功能,可以简化这个方法,但是这里没有利用这一点
long interval = System.currentTimeMillis() - creationTime;
String tmpStr = " " + ( interval / 1000.0 ) + "000";
int pos = tmpStr.indexOf(".");
String secStr = tmpStr.substring(pos - 2, pos + 4);
String nameStr = " " + Thread.currentThread().getName();
nameStr = nameStr.substring(nameStr.length() - 8, nameStr.length());
System.out.println(secStr + " " + nameStr + ": " + msg);
}
public static void main(String[] args) {
try {
//通过该构造函数可以获取实时时钟的当前时间
VolatileDemo vol = new VolatileDemo();
//稍停100ms,以让实时时钟稍稍超前获取时间,使print()中创建的消息打印的时间值大于0
Thread.sleep(100);
Thread t = new Thread(vol);
t.start();
//休眠100ms,让刚刚启动的线程有时间运行
Thread.sleep(100);
//workMethod方法在main线程中运行
vol.workMethod();
} catch ( InterruptedException x ) {
System.err.println("one of the sleeps was interrupted");
}
}
}
参考的帖子及文章
http://blog.csdn.net/ns_code/article/details/17101369
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html (写的相当的好)
JAVA 并发实现六(Volatile的使用)的更多相关文章
- Java并发(六):volatile的实现原理
synchronized是一个重量级的锁,volatile通常被比喻成轻量级的synchronized volatile是一个变量修饰符,只能用来修饰变量. volatile写:当写一个volatil ...
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- (转)Java并发编程:volatile关键字解析
转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...
- 【死磕Java并发】-----深入分析volatile的实现原理
通过前面一章我们了解了synchronized是一个重量级的锁,虽然JVM对它做了很多优化,而下面介绍的volatile则是轻量级的synchronized.如果一个变量使用volatile,则它 ...
- Java 并发编程:volatile的使用及其原理
Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...
- Java并发编程:volatile关键字解析(转载)
转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 Java并发编程:volatile关键字解析 ...
- Java并发编程:volatile关键字解析-转
Java并发编程:volatile关键字解析 转自海子:https://www.cnblogs.com/dayanjing/p/9954562.html volatile这个关键字可能很多朋友都听说过 ...
- Java并发编程:volatile关键字解析(学习总结-海子)
博文地址:Java并发编程:volatile关键字解析
- 6、Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
随机推荐
- [转] Ubuntu 12.04下LAMP安装配置 (Linux+Apache+Mysql+PHP)
我是一个Linux新手,想要安装一台Ubuntu 12.04版的Linux服务器,用这台服务器上的LAMP套件来运行我自己的个人网站.LAMP套件就是 “Linux+Apache+Mysql+PHP这 ...
- C++ STL set集合容器
汇总了一些set的常用语句,部分参考了这篇:http://blog.163.com/jackie_howe/blog/static/199491347201231691525484/ #include ...
- vsftp的设置选项
设置匿名用户上传的文件的权限: anon_umask= 匿名用户新增文件的umask 数值.默认值为077. VSFTPD的设置选项 VSFTPD的配置文件/etc/vsftpd/vsftp ...
- NetBeans使用技巧记录
1.窗体字体大小设置: 在etc文件夹下的netbeans.conf中添加,12表示字体大小,12正合适. netbeans_default_options="--fontsize 12 - ...
- new date() 函数在浏览器中的兼容问题!!
引言: 同一种语言javascript,在不同的浏览器中,存在语言兼容性问题,本质上是由于不同的浏览器是支持的语言标准和实现上各有差异.本文将基于new Date来创建Date对象来分析这个问题. v ...
- Mysql 视图笔记2
这学期开了数据库的课,对sql注入颇感兴趣.因此,对数据库语句也颇为喜爱.遇到了with check option 问题.这属于sql view里面的一个问题.在此略做小结.大牛勿喷! 先自定义一个t ...
- java对象初级知识
this属于类 方法中没有自己的this指针(本来以为js方法中有,其实并没有里,那是被new出来的function 在声明的时候可以赋初值: int a =12 但不能 int a ; a ...
- Linux 从 sar 到 sar2html 的认识
这些变形的工具.诸如:淘宝的Tsar.ksar.sar2html....等.都是通过抓取 sar的数据 所以在最终呈现的数据上变化不大.只是展现的手段和效果不一样而已 sar 是帮助我们 ...
- JavaScript不一样的语法
JavaScript除了面向对象的部分,基本语法和C语言类似,但是也有一些自己的特别之处,现总结如下: (1)break和continue后面可以跟label 语法: break labelname; ...
- 为Linux服务器伪装上Windows系统假象
网络上的计算机很容易被黑客利用工具或其它手段进行扫描,以寻找系统中的漏洞,然后再针对漏洞进行攻击. 通过伪装Linux系统,给黑客设置系统假象,可以加大黑客对系统的分析难度,引诱他们步入歧途,从而进一 ...