[問題] 一個 singleton? 的問題
各位板友好,最近遇到了一個跟 Singleton? 有關的問題想請教一下,
程式碼是憑印象大略打的,所以有誤的話還請見諒 QQ
class Single {
private static Single mInstance;
public static Single getInstance() {
if (mInstance == null) {
mInstance = new Single();
}
return mInstance;
}
private Single(){}
public static void reset() {
mInstance = null;
}
}
這是一個簡單的 singleton,先忽略第一次 getInstance() thread safe的問題,
這個instance會在程式內被很頻繁的使用到,
當遇到某個特別的情況時,
"必須"要把 call reset() 這個方法來讓 mInstance 重新 new,
但 call reset() 跟 call getInstance() 是不同的 thread,
由於是不同thread所以在 reset() 後 getInstance() 有機率造成 NPE,
所以我把 Single 程式稍微修改一下如下 SingleA
class SingleA {
private static SingleA mInstance;
private static final Object SYNC = new Object();
public static SingleA getInstance() {
synchronized(SYNC){
if (mInstance == null) {
mInstance = new SingleA();
}
}
return mInstance;
}
private SingleA(){}
public static void reset() {
synchronized(SYNC){
mInstance = null;
mInstance = new SingleA();
}
}
}
說到這裡,想請問的問題有幾個,
1. 想確認第一段程式碼中造成 NPE 是否真的是因為 thread unsafe的關係?
(程式碼中都會把 getInstance 用一個 local variable 存起來,
例如 Single single = Single.getInstance(); )
造成的原因是 thread 1 call getInstance 當通過 if(mInstance == null)
的判斷後 thread 2 call reset 所以導致 thread 1 最後 return null 嗎?
2. 如果問題一中我的推論是正確的 (也就是 npe 是 thread unsafe 造成的)
那請問 SingleA 這樣修改是正確(正確的定義是 thread safe) 的嗎?
3. 如果 SingleA 是 thread safe 的話,想請問有沒有其他更好的方法
可以達成呢?因為 getInstance() 會很頻繁的使用,所以不太希望
裡面會有 synchronized 。
如果有什麼不清楚的還請見諒 QQ
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.135.114.160
推
12/29 10:24, , 1F
12/29 10:24, 1F
→
12/29 10:25, , 2F
12/29 10:25, 2F
→
12/29 10:27, , 3F
12/29 10:27, 3F
QQ 但這是個數十萬行架構的程式碼 小弟把問題先簡化而已
在以前的情況下因為可以保證第一次new instance 是thread safe,
而且也不會把 instance 設成 null,所以以前沒遇到這種問題。
※ 編輯: qweqweqweqwe 來自: 220.135.114.160 (12/29 12:58)
→
12/29 13:33, , 4F
12/29 13:33, 4F
→
12/29 13:35, , 5F
12/29 13:35, 5F
喔喔 不好意思忘了打上 static , 已經補上了謝謝提醒
另外上面有提到
系統第一次 Single.getInstance() 的 initialization 時"一定保證"是 thread safe ,
所以原本的 Single.getInstance() 並不需要加上 synchronized。
※ 編輯: qweqweqweqwe 來自: 220.135.114.160 (12/29 14:04)
※ 編輯: qweqweqweqwe 來自: 36.224.104.196 (12/29 20:29)
推
12/30 11:47, , 6F
12/30 11:47, 6F
討論串 (同標題文章)
完整討論串 (本文為第 1 之 3 篇):
java 近期熱門文章
PTT數位生活區 即時熱門文章