Java中的兩重檢討(Double-Check)詳解。本站提示廣大學習愛好者:(Java中的兩重檢討(Double-Check)詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是Java中的兩重檢討(Double-Check)詳解正文
在 Effecitve Java 一書的第 48 條中提到了兩重檢討形式,並指出這類形式在 Java 中平日其實不實用。該形式的構造以下所示:
public Resource getResource() { if (resource == null) { synchronized(this){ if (resource==null) { resource = new Resource(); } } } return resource; }
該形式是對上面的代碼改良:
public synchronized Resource getResource(){ if (resource == null){ resource = new Resource(); } return resource; }
這段代碼的目標是對 resource 延遲初始化。然則每次拜訪的時刻都須要同步。為了削減同步的開支,因而有了兩重檢討形式。
在 Java 中兩重檢討形式有效的緣由是在分歧步的情形下援用類型不是線程平安的。關於除 long 和 double 的根本類型,兩重檢討形式是實用 的。好比上面這段代碼就是准確的:
private int count; public int getCount(){ if (count == 0){ synchronized(this){ if (count == 0){ count = computeCount(); //一個耗時的盤算 } } } return count; }
下面就是關於java中兩重檢討形式(double-check idiom)的普通結論。然則工作還沒有停止,由於java的內存形式也在改良中。Doug Lea 在他的文章中寫道:“依據最新的 JSR133 的 Java 內存模子,假如將援用類型聲明為 volatile,兩重檢討形式便可以任務了”。所以今後要在 Java 中應用兩重檢討形式,可使用上面的代碼:
private volatile Resource resource; public Resource getResource(){ if (resource == null){ synchronized(this){ if (resource==null){ resource = new Resource(); } } } return resource; }
固然了,得是在遵守 JSR133 標准的 Java 中。
所以,double-check 在 J2SE 1.4 或晚期版本在多線程或許 JVM 調優時因為 out-of-order writes,是弗成用的。 這個成績在 J2SE 5.0 中曾經被修復,可使用 volatile 症結字來包管多線程下的單例。
public class Singleton { private volatile Singleton instance = null; public Singleton getInstance() { if (instance == null) { synchronized(this) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
推舉辦法 是Initialization on Demand Holder(IODH),
public class Singleton { static class SingletonHolder { static Singleton instance = new Singleton(); } public static Singleton getInstance(){ return SingletonHolder.instance; } }
以上就是本文的全體內容,願望對年夜家進修java法式設計有所贊助。