最近在看HashMap的过程中去了解啦java 的两个关键字,transient 和 volatile 。
1.transient
我们都知道实现serializable接口可以实现java对象的序列化和反序列化,但如果不想序列化该对象其中的一个属性,可以在这个对象类中用transient关键字修饰该变量,被修饰的这个变量在序列化的过程中不会像其他变量一样进行串行化。
代码举例:这里不希望这个测试javaBean在文件写出读入的过程中传输其pwd属性
LoggingInfo.java
public class LoggingInfo implements Serializable{
private static Date loggingDate = new Date();
private String uid;
private transient String pwd;
public static Date getLoggingDate() {
return loggingDate;
}
public static void setLoggingDate(Date loggingDate) {
LoggingInfo.loggingDate = loggingDate;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public LoggingInfo(String uid, String pwd) {
super();
this.uid = uid;
this.pwd = pwd;
}
public String toString() {
//因为pwd是transient的 这里在toString方法中判断是否在传输中 pwd这个变量 是否被持久化
if (null == pwd) {
pwd = "Not Set";
}
return "login info: \n" + "user" + uid +
"\n logging date: " + loggingDate.toString() + "\n password: " + pwd;
}
}
进行传输的主函数:
package testTransient;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Test {
public static void main(String[] args) {
LoggingInfo loggingInfo = new LoggingInfo("longyin", "123");
System.out.println("写入:" + loggingInfo);
ObjectOutputStream objectOutputStream = null;
ObjectInputStream objectInputStream = null;
try {
//写出
objectOutputStream = new ObjectOutputStream(new FileOutputStream("test.txt"));
//读入
objectInputStream = new ObjectInputStream(new FileInputStream("test.txt"));
objectOutputStream.writeObject(loggingInfo);
LoggingInfo info=(LoggingInfo) objectInputStream.readObject();
System.out.println("读取:" + info);
System.out.println("是否相等:" + (info.getPwd().equals(loggingInfo.getPwd())));
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
objectOutputStream.close();
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
最后运行的结果:
2.volatile关键字
Java 语言提供了一种稍弱的同步机制,即 volatile 变量.用来确保将变量的更新操作通知到其他线程,保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新. 当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的.
volatile 变量对所有线程是立即可见的,对 volatile 变量所有的写操作都能立即反应到其他线程之中,换句话说:volatile 变量在各个线程中是一致的,所以基于 volatile 变量的运算是线程安全的.
下面只是个人的理解:
1。如果在类中使用volatile修饰一个变量,并且是static的类型,那么该变量属于类,是类变量,那么即使多个线程访问该变量访问的也是同一个,哪个线程改变它的话,其他线程在访问它的时候就是最新的值。不存在不同步的问题。
2。如果在类中使用volatile修饰的变量没有使用static修饰,那就属于成员变量,那么多个线程在访问的时候,访问同一个对象下的该成员变量也不存在不同步的问题。对于同一个对象,该成员变量就一个!线程无论何时访问都是最新的。
所以能用到volatile关键字解决多线程的不同步问题相当少了。