java裏面的transient和volatile

transient

transient是類型修飾符,只能用來修飾字段。在對象序列化的過程中,標記爲transient的變量不會被序列化。

我們知道,把一個對象寫入到文件裏面,是要對對象進行序列化的,不然會報錯,例如一下,對TestBean這個類進行了序列化,但是對其屬性address加了一個transient修飾符,說明這個屬性不需要序列化,所以address的值不會寫入到文件裏面去,看代碼:

public class TestTransient {

	public static void main(String[] args) {
		TestBean tb = new TestBean();
		tb.setId(23);
		tb.setName("文三路");
		tb.setAddress("浙江省杭州市");
		try {
			ObjectOutput oo = new ObjectOutputStream(new FileOutputStream(
					new File("D:\\a\\c.txt")));
			oo.writeObject(tb);
			oo.flush();
			oo.close();
			ObjectInput oi = new ObjectInputStream(new FileInputStream(
					new File("D:\\a\\c.txt")));
			TestBean bt2 = (TestBean)oi.readObject();
			System.out.println(bt2.getId());
			System.out.println(bt2.getName());
			System.out.println(bt2.getAddress());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

class TestBean implements Serializable {
	private static final long serialVersionUID = 1158373645442538730L;
	private int id;
	private String name;
	private transient String address;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

}

打印結果是:

23

文三路

null

如果把TestBean的address屬性的transient修飾符去掉,則打印:

23

文三路

浙江省杭州市

=====================================================================

volatile
volatile也是變量修飾符,只能用來修飾變量。volatile修飾的成員變量在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值。而且,當成員變量發生變化時,強迫線程將變化值回寫到共享內存。這樣在任何時刻,兩個不同的線程總是看到某個成員變量的同一個值。

Java使用一個主內存來保存變量當前值,而每個線程則有其獨立的工作內存。線程訪問變量的時候會將變量的值拷貝到自己的工作內存中,這樣,當線程對自己工作內存中的變量進行操作之後,就造成了工作內存中的變量拷貝的值與主內存中的變量值不同。

Java語言規範中指出:爲了獲得最佳速度,允許線程保存共享成員變量的私有拷貝,而且只當線程進入或者離開同步代碼塊時才與共享成員變量的原始值對比。

這樣當多個線程同時與某個對象交互時,就必須要注意到要讓線程及時的得到共享成員變量的變化。

而volatile關鍵字就是提示VM:對於這個成員變量不能保存它的私有拷貝,而應直接與共享成員變量交互。

使用建議:在兩個或者更多的線程訪問的成員變量上使用volatile。當要訪問的變量已在synchronized代碼塊中,或者爲常量時,不必使用。

由於使用volatile屏蔽掉了VM中必要的代碼優化,所以在效率上比較低,因此一定在必要時才使用此關鍵字。

參考自:http://heaven-arch.iteye.com/blog/1160693


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章