你們不是排隊等著進來吃果果嗎?進來了我再來check一次,這下不可能產出10個了吧。看起來已經完美了,可惜還是不行。這個可能不太好理解,但是下面這一行不是atomic的操作,它實際被分成幾個步驟:allocate memory, assign allocated memory to instance ref, initialize the object Smarty into the allocated memory.instance = new Smarty();
所以說如果線程1卡在第三步那裡,線程2高高興興滴進來拿instance了,他會拿到一個還沒煮好的蛋,吃下去,完蛋了。有個keyword,可能一般你很少用到,叫volatile:
public class Smarty {
private static volatile Smarty instance;
private Smarty() {}
public static Smarty getInstance() {
if(instance == null) {
synchronized(Smarty.class) {
if(instance == null) {
instance = new Smarty();
}
}
}
return instance;
}
}
複製代碼
volatile是什麼鬼?看看定義:What is the Java volatile keyword?Essentially, volatile is used to indicate that a variable's value will be modified by different threads .Declaring a volatile Java variable means:The value of this variable will never be cached thread-locally : all reads and writes will go straight to "main memory";Access to the variable acts as though it is enclosed in a synchronized block , synchronized on itself.第二點,正是我們需要的,我還沒煮完的雞蛋你先別拿。恩,終於可以了。但是,據說大部分JVM的implementation並不尊重volatile的規則。完蛋啦,搞了半天還是沒法確定可以完美做singleton。別緊張,這樣寫就沒問題了。正確的Java Singleton寫法:
public class Smarty {
private Smarty() {}
private static class SmartyLoader {
private static final Smarty instance = new Smarty();