zoukankan
html css js c++ java
Java transient关键字
Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到主内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
由于使用volatile屏蔽掉了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的代码:
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: " + "user: " + uid +
" logging date : " + loggingDate.toString() +
" password: " + password;
}
}
现在我们创建一个这个类的实例,并且串行化(serialize)它 ,然后将这个串行化对象写如磁盘。
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"
。当从磁盘中读出某个类的实例时,实际上并不会执行这个类的构造函数,
而是载入了一个该类对象的持久化状态,并将这个状态赋值给该类的另一个对象。
查看全文
相关阅读:
leetcode 175 Combine Two Tables join用法
spark学习及环境配置
html表格设计
免费的论文查重网站
php利用msqli访问数据库并实现分页,
php利用href进行页面传值的正确姿势
php+mysql时报错:Unknown column '' in 'field list'解决方案
使用XMLHttpRequest解析json
用自定义的函数将gps转换为高德坐标
WeakHashMap回收时机
原文地址:https://www.cnblogs.com/apache-x/p/5502541.html
最新文章
【Luogu】P2495消耗战(虚树DP)
【Luogu】P2805植物大战僵尸(拓扑排序+最大流)
【Luogu】P2604网络扩容(费用流乱搞)
2.bash术语定义
1.bash总体介绍
14. Redis配置统计字典
13. Redis监控运维云平台CacheCloud
12.Redis运维点
11.Redis缓存设计
10.Redis分布式集群
热门文章
9.Redis高可用-哨兵
[编程题] 小易喜欢的数列 dp
57. 三数之和
17965 幸运之星(优先做) 约瑟夫环问题O(n)
leetcode 620. Not Boring Movies 用where语句判断
leetcode 627. Swap Salary 数据库带判断的更新操作
leetcode 182. Duplicate Emails having的用法 SQL执行顺序
leetcode 181 Employees Earning More Than Their Managers 不会分析的数据库复杂度
17082 两个有序数序列中找第k小(优先做) O(logn)
leetcode 176. Second Highest Salary
Copyright © 2011-2022 走看看