诗特林-sterning
posts - 310, comments - 6939, trackbacks - 0, articles - 3
BlogJava
::
首页
::
新随笔
::
联系
::
聚合
::
管理
Think in Java 4th--Java中的volatile
Posted on 2007-09-11 14:31
诗特林
阅读(1702)
评论(2)
编辑
收藏
所属分类:
Think In Java 4th
Think in Java 4th--Java中的volatile
我们知道,在Java中设置变量值的操作,除了long和double类型的变量外都是原子操作,也就是说,对于变量值的简单读写操作没有必要进行同步。
这在JVM 1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。
在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。
要解决这个问题,只需要像在本程序中的这样,把该变量声明为volatile(不稳定的)即可,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。
Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
请看如下示例:
1
package
ch17_concurrency;
2
3
4
class
UnresponsiveUI
{
5
private
volatile
double
d
=
1
;
6
public
UnresponsiveUI()
throws
Exception
{
7
while
(d
>
0
)
{
8
d
=
d
+
(Math.PI
+
Math.E)
/
d;
9
}
10
System.in.read();
11
}
12
}
13
14
public
class
_19_ResponsiveUI
extends
Thread
{
15
private
static
volatile
double
d
=
1
;
16
public
_19_ResponsiveUI()
{
17
setDaemon(
true
);
18
start();
19
}
20
public
void
run()
{
21
while
(
true
)
{
22
//
System.out.println(d);
23
d
=
d
+
(Math.PI
+
Math.E)
/
d;
24
}
25
}
26
27
public
static
void
main(String[] args)
throws
Exception
{
28
//
TODO Auto-generated method stub
29
//
new UnresponsiveUI();
30
new
_19_ResponsiveUI();
31
System.in.read();
32
System.out.println(d);
33
}
34
35
}
36
评论
#
re: Think in Java 4th--Java中的volatile
回复
更多评论
2007-09-11 16:48 by
dennis
volatile需要强调的一点就是,它仅仅保证多线程环境下的可见性,不保证操作的原子性,举的例子不大恰当吧,想更多了解还是看看这个帖子
http://www.javaeye.com/topic/109150
#
re: Think in Java 4th--Java中的volatile[未登录]
回复
更多评论
2008-05-23 14:26 by
dd
简单点就是线程在运行的时候为了提高效率所以被允许偷一点点懒,即忽视多线程的可能,不更新主存中的原本(线程使用的值是副本)。
VOLATILE即告诉JVM,不能偷懒!
这个特性应该是从C移植过来的。而C是没有线程的,所以说,JAVA的线程其实做得很勉强。
因为从语义的角度讲,线程的这种偷懒工作方式应该是不被允许的。JVM首先应该保证正确性(主存跟工作区的同步),然后再考虑性能优化。不正确的东西,性能再好也是白搭。
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
管理
相关文章:
Thinking in Java 第四版(完全)及源代码
Think in Java 4th--Java中的volatile
Powered by:
BlogJava
Copyright © 诗特林
日历
<
2007年9月
>
日
一
二
三
四
五
六
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
随笔分类
.NET(4)
Android(4)
BI(12)
Bing MAP(2)
C#(3)
DesignPattern(3)
English(30)
Firend Blog(1)
GIS(14)
Google(15)
J2EE(30)
J2ME(3)
Java(16)
JavaScript(8)
Java与外企(13)
JPA(2)
JSF(9)
Oracle(33)
PMP(6)
SAP(25)
Socket(10)
Spring(1)
Struts(12)
Swing(3)
Think In Java 4th(2)
图形天下(3)
生活随笔(20)
系统架构(7)
职场(2)
软件测试(3)
项目管理(10)
随笔档案
2010年12月 (1)
2010年9月 (1)
2010年8月 (2)
2010年7月 (3)
2010年6月 (3)
2010年5月 (2)
2010年4月 (7)
2010年3月 (4)
2010年2月 (2)
2010年1月 (4)
2009年11月 (4)
2009年10月 (7)
2009年9月 (4)
2009年8月 (5)
2009年7月 (4)
2009年6月 (4)
2009年5月 (6)
2009年4月 (12)
2009年3月 (7)
2009年2月 (3)
2009年1月 (5)
2008年12月 (2)
2008年11月 (2)
2008年10月 (6)
2008年9月 (4)
2008年7月 (6)
2008年6月 (22)
2008年5月 (4)
2008年4月 (13)
2008年3月 (3)
2008年2月 (1)
2008年1月 (26)
2007年12月 (20)
2007年11月 (11)
2007年10月 (35)
2007年9月 (30)
2007年8月 (15)
2007年7月 (7)
2007年5月 (1)
2006年8月 (4)
2006年7月 (8)
相册
书法
搜索
积分与排名
积分 - 1370728
排名 - 18
最新评论
1. re: ORACLE directory 目录
备份中使用到了,加油研究
--Glorin
2. re: Struts2+Spring2+Hibernate3 web应用示例(七)
增删改查 小白在学习中 楼主多多关照尼谢谢
--小石同学
3. re: Struts2+Spring2+Hibernate3 web应用示例(七)
楼主 能不能把 Struts2+Spring2+Hibernate3工程都发我一份
960760087@qq.com 谢谢楼主
--小石同学
4. re: 用Java实现FTP批量大文件上传下载(六)--代码及示例下载
楼主真大神, 我最近在做FTP批量下载图片,但是遇到不少问题,如果能发一份源给我,我真的万分感激 ,我的邮箱是450479001@qq.com
--啊谦
5. re: Java做的酒店管理系统(C/S)源码
可以麻烦楼主发一份给我吗,最近在做这方面的作业,想学习学习,,谢谢楼主了!1587122459@qq.com
--肖敏
阅读排行榜
1. 多线程Java Socket编程示例(92531)
2. Java基于Socket文件传输示例(91357)
3. Eclipse中最常用的10个快捷键(48691)
4. 用Java实现FTP批量大文件上传下载(一)(41099)
5. Struts2+Spring2+Hibernate3 web应用示例(一)(40691)
评论排行榜
1. Java做的酒店管理系统(C/S)源码(2300)
2. 基于WEB的批量大文件上传下载技术共享(含源代码)(988)
3. 系统分析师最新资料(720)
4. Thinking in Java 第四版(完全)及源代码(673)
5. 共享到底-软件设计师(高级程序员)资料(264)