网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  破除java神话之原子操作都是线程安全的     
  文章作者:未知  文章来源:水木森林  
  查看:64次  录入:管理员--2007-11-17  
 
  java中原子操作是线程安全的论调经常被提到。根据定义,原子操作是不会被打断地的操作,因此被认为是线程安全的。实际上有一些原子操作不一定是线程安全的。
  
  这个问题出现的原因是尽量减少在代码中同步关键字。同步会损害性能,虽然这个损失因jvm不同而不同。另外,在现代的jvm中,同步的性能正在逐步提高。尽管如此,使用同步仍然是有性能代价的,并且程序员永远会尽力提高他们的代码的效率,因此这个问题就延续了下来。
  
  在java中,32位或者更少位数的赋值是原子的。在一个32位的硬件平台上,除了double和long型的其它原始类型通常都是使用32位进行表示,而double和long通常使用64位表示。另外,对象引用使用本机指针实现,通常也是32位的。对这些32位的类型的操作是原子的。
  
  这些原始类型通常使用32位或者64位表示,这又引入了另一个小小的神话:原始类型的大小是由语言保证的。这是不对的。java语言保证的是原始类型的表数范围而非jvm中的存储大小。因此,int型总是有相同的表数范围。在一个jvm上可能使用32位实现,而在另一个jvm上可能是64位的。在此再次强调:在所有平台上被保证的是表数范围,32位以及更小的值的操作是原子的。
  
  那么,原子操作在什么情况下不是线程安全的?主要的一点是他们也许确实是线程安全的,但是这没有被保证!java线程允许线程在自己的内存区保存变量的副本。允许线程使用本地的私有拷贝进行工作而非每次都使用主存的值是为了提高性能。考虑下面的类:
  
  
  class realtimeclock
  {
   private int clkid;
   public int clockid()
   {
   return clkid;
   }
   public void setclockid(int id)
   {
   clkid = id;
   }
  //...
  }
  
  现在考虑realtimeclock的一个实例以及两个线程同时调用setclockid和clockid,并发生以下的事件序列:
  
  t1 调用setclockid(5)
  t1将5放入自己的私有工作内存
  t2调用setclockid(10)
  t2将10放入自己的私有工作内存
  t1调用clockid,它返回5
  5是从t1的私有工作内存返回的
  
  对clocki的调用应该返回10,因为这是被t2设置的,然而返回的是5,因为读写操作是对私有工作内存的而非主存。赋值操作当然是原子的,但是因为jvm允许这种行为,因此线程安全不是一定的,同时,jvm的这种行为也不是被保证的。
  
  两个线程拥有自己的私有拷贝而不和主存一致。如果这种行为出现,那么私有本机变量和主存一致必须在以下两个条件下:
  
  1、变量使用volatile声明
  2、被访问的变量处于同步方法或者同步块中
  
  如果变量被声明为volatile,在每次访问时都会和主存一致。这个一致性是由java语言保证的,并且是原子的,即使是64位的值。(注意很多jvm没有正确的实现volatile关键字。你可以在www.javasoft.com找到更多的信息。)另外,如果变量在同步方法或者同步块中被访问,当在方法或者块的入口处获得锁以及方法或者块退出时释放锁是变量被同步。
  使用任何一种方法都可以保证clockid返回10,也就是正确的值。变量访问的频度不同则你的选择的性能不同。如果你更新很多变量,那么使用volatile可能比使用同步更慢。记住,如果变量被声明为volatile,那么在每次访问时都会和主存一致。与此对照,使用同步时,变量只在获得锁和释放锁的时候和主存一致。但是同步使得代码有较少的并发性。
  
  如果你更新很多变量并且不想有每次访问都和主存进行同步的损失或者你因为其它的原因想排除并发性时可以考虑使用同步。
 
 
上一篇: java的线程安全四种方式五个等级    下一篇: java线程总结
  相关文档
sun新添java xml pack套包 11-17
spring数据访问对象(dao)框架入门 11-17
getfileversion 方法 11-16
如何用Java实现Web服务器 04-14
java中的指针,引用及对象的clone 11-17
java servlet api说明文档(2.1a版)(三) 11-17
实战 j2ee 开发购物网站 开发环境篇 11-17
“三步走”成为一名优秀的程序员 11-17
sun.xvr-1200图形加速器的使用 11-17
大同公司compstation u4mp服务器 11-17
java程序编码规范 11-17
xml和java:一个强大的组合 11-17
抽象类(abstract class)和接口(interface) 11-17
ajax技术:构建动态的java应用程序分析 11-16
使用netbeans ide 4.1开发java应用程序 11-17
jfc/swing活学活用系列之定制jlist显示 11-16
JAVA技术:上传图片的缩放处理 08-06
java知识:class.forname的含义 11-20
仔细触摸java编程中的“文档”和“包” 11-16
eclipse插件开发之easyexplorer 11-16
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息