Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。
我们知道,在Java中设置变量值的操作,除了long和double类型的变量外都是原子操作,也就是说,对于变量值的简单读写操作没有必要进行同步。
这在JVM 1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。
在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。
要解决这个问题,只需要像在本程序中的这样,把该变量声明为volatile(不稳定的)即可,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。
Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
由于使用屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
java关键字Transient
转自http://horst.sun.blog.163.com/blog/static/348849612007614494492/
翻译自http:。 //www.devx.com/tips/Tip/13726
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想
用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
注意static变量也是可以串行化的
首先,让我们看一些Java serialization的代码:
现在我们创建一个这个类的实例,并且串行化(serialize)它 ,然后将这个串行化对象写入磁盘。 public class LoggingInfo implements java.io.Serializable
{
private Date loggingDate = new Date();
private String uid;
private transient String pwd;
LoggingInfo(String user, String password)
{
uid = user;
pwd = password;
}
public String toString()
{
String password=null;
if(pwd == null)
{
password = "NOT SET";
}
else
{
password = pwd;
}
return "logon info: \n " + "user: " + uid +
"\n logging date : " + loggingDate.toString() +
"\n password: " + password;
}
}
LoggingInfo logInfo = new LoggingInfo("MIKE", "MECHANICS"); System.out.println(logInfo.toString()); try { ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("logInfo.out")); o.writeObject(logInfo); o.close(); } catch(Exception e) {//deal with exception} To read the object back, we can write try { ObjectInputStream in =new ObjectInputStream( new FileInputStream("logInfo.out")); LoggingInfo logInfo = (LoggingInfo)in.readObject(); System.out.println(logInfo.toString()); } catch(Exception e) {//deal with exception}
如果我们运行这段代码,我们会注意到从磁盘中读回(read——back (de-serializing))的对象打印password为"NOT SET"。这是当我们定义pwd域为transient时,所期望的正确结果。
现在,让我们来看一下粗心对待transient域可能引起的潜在问题。假设我们修改了类定义,提供给transient域一个默认值,
代码如下:
public class GuestLoggingInfo implements java.io.Serializable { private Date loggingDate = new Date(); private String uid; private transient String pwd; GuestLoggingInfo() { uid = "guest"; pwd = "guest"; } public String toString() { //same as above } }
现在,如果我们穿行化GuestLoggingInfo的一个实例,将它写入磁盘,并且再将它从磁盘中读出,我们仍然看到读回的对象打印password 为 "NOT SET"。当从磁盘中读出某个类的实例时,实际上并不会执行这个类的构造函数, 而是载入了一个该类对象的持久化状态,并将这个状态赋值给该类的另一个对象。
发表评论
-
((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()
2012-02-29 10:54 1394getClass().getGenericSuperclass ... -
Java的内存泄露的原因与防止
2011-11-04 16:02 1379http://www.lybbs.net/news_r ... -
Java内存泄露的理解与解决【转】
2011-11-04 15:33 690Java内存管理机制 在C++语言中,如果需要动态分配一块内 ... -
深入Java核心 Java内存分配原理精讲
2011-11-02 22:17 591Java内存分配与管理是Jav ... -
forward和redirect的区别
2011-10-31 15:35 676forward和redirect的区别 ... -
【Java复习】第十讲 JDBC编程
2011-09-29 14:11 917JDBC(Java data Base Connectivit ... -
【Java复习】第九讲 JSP与Servlet
2011-09-29 13:32 1046课前索引 1. 动态网页和静态网页有什么区别?2. 什么是W ... -
【Java复习】第九讲 JavaBean和RMI
2011-09-28 21:26 838【课前思考】 1. ... -
【Java复习】第八讲 Java网络编程
2011-09-28 17:15 1014课前索引 课前思考 1. 什么是TCP/ IP协议? 2 ... -
【Java复习】第七讲 Swing用户界面设计
2011-09-28 17:12 1851课前索引 【课前思考】 1. 什么是Swing?它和AWT ... -
【Java复习】第六讲 Java的线程和Java Applet
2011-09-28 16:05 1532课前索引 【课前思考】 1. 什么是线程?它和进程有什么区 ... -
【Java复习】第五讲 AWT图形用户界面设计
2011-09-28 10:12 1598课前索引 【课前思考】 1. java语言是跨平台的编程语 ... -
【Java复习】第四讲 Java的例外处理和I/O流
2011-09-27 21:50 1316【课前思考】 1. 什么是例外?Java中有哪两种例外处 ... -
【Java复习】第三讲 Java语言中的面向对象特性
2011-09-27 17:20 910课前索引 【课前思考】 1. 什么是对象?什么是类?什 ... -
【Java复习】第二讲 Java语言基础知识
2011-09-27 16:26 1095概述: 【课前思考】 1. Java中的标识符是 ... -
【Java复习】第一讲 Java语言概述
2011-09-27 16:10 931★ 第一讲 Java语言概述 【课前思考】 ...
相关推荐
java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java ...
java volatile 关键字 学习
从JUC中的AQS引入,讲解Java volatile与AQS锁内存可见性
主要讲述java线程volatile关键字
【Java面试题】volatile的作用
主要介绍了Java Volatile 变量详解及使用方法的相关资料,需要的朋友可以参考下
Java并发编程:volatile关键字解析
主要介绍了java volatile关键字使用方法及注意事项的相关资料,当一个变量被声明为 volatile 后,java 内存模型确保所有使用该变量的线程能看到相同的、一致的值。,需要的朋友可以参考下
violate java_Java 之 volatile 超级详解
在本文里我们给大家分享的是关于java volatile关键字作用及使用场景的相关知识点内容,需要的朋友们学习下。
java语言的volatile教程,java语言的volatile关键字到底怎么用
Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;
主要介绍了简单了解volatile关键字实现的原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
volatile是java中的关键词之一,这篇文章主要给大家介绍了关于Java中volatile关键字的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
volatile这个关键字,不仅仅在Java语言中有,在很多语言中都有的,而且其用法和语义也都是不尽相同的。这篇文章主要介绍了Java中的volatile关键字,需要的朋友可以参考下
主要介绍了java 中volatile和lock原理分析的相关资料,需要的朋友可以参考下
主要介绍了java 高并发中volatile的实现原理的相关资料,在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”,需要的朋友...