Volatile
Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到主内存。
这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。 而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。 由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
Transient
Transient修饰的成员变量不会被序列化
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。 为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。 注意static变量也是可以串行化的
example
首先,让我们看一些Java serialization的代码:
- 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;
- }
- }
现在我们创建一个这个类的实例,并且串行化(serialize)它 ,然后将这个串行化对象写如磁盘。
- class Scratch {
- public static void main(String[] args) {
- 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"。 当从磁盘中读出某个类的实例时,实际上并不会执行这个类的构造函数, 而是载入了一个该类对象的持久化状态,并将这个状态赋值给该类的另一个对象。
相关推荐
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关键字使用方法及注意事项的相关资料,当一个变量被声明为 volatile 后,java 内存模型确保所有使用该变量的线程能看到相同的、一致的值。,需要的朋友可以参考下
Java并发编程:volatile关键字解析
在本文里我们给大家分享的是关于java volatile关键字作用及使用场景的相关知识点内容,需要的朋友们学习下。
violate java_Java 之 volatile 超级详解
GMW 15634-2020 Determination of Volatile and Semi-Volatile Organic Compounds.pdf
GMW 15654-2020 Determination of Volatile and Semi-Volatile Organic Compounds.pdf
GMW 15654-2013 Determination of Volatile and Semi-Volatile Organic Compounds.pdf
java语言的volatile教程,java语言的volatile关键字到底怎么用
主要介绍了简单了解volatile关键字实现的原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;
volatile是java中的关键词之一,这篇文章主要给大家介绍了关于Java中volatile关键字的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧