我亦無他,唯手熟爾!多線程下的單例設計模式
眾所周知,單例模式中,構造方法是私人化的,通過靜態方法內部調用建構函式返回該類的執行個體對象。常見的代碼如下所示:
?
| 12345678910 |
public class Singleton { private
static Singleton singletonObj;
private
Singleton(){} public
static Singleton getInstance(){ if(singletonObj ==
null){ singletonObj =
new Singleton(); } return
singletonObj; }} |
在單線程的情況下,確實可以保證只有一個執行個體,但是在多線程的情況下,就會發生意想不到的情況。
建立一個TestSingleton類,如下:
?
public class TestSingleton implements
Runnable { private
Singleton s = null; public
Singleton getS() { return
s; } public
void setS(Singleton s) { this.s = s; } public
static void main(String[] args) { TestSingleton ts1 =
new TestSingleton(); TestSingleton ts2 =
new TestSingleton(); Thread t1 =
new Thread(ts1); Thread t2 =
new Thread(ts2); t1.start(); t2.start(); Singleton s1 = ts1.getS(); Singleton s2 = ts2.getS(); System.out.println(s1 == s2); } @Override public
void run() { s = Singleton.getInstance(); }} |
運行結果返回 false
在多線程的環境中需要考慮同步的問題,對上述單例模式的代碼進行修改,如下:
?
public static Singleton getInstance() { if
(singletonObj == null) { synchronized
(Singleton.class) { if
(singletonObj == null) { singletonObj =
new Singleton(); } } } return
singletonObj; } |
重新運行上述TestSingleton ,返回結果 true 此時,保證即使是在多線程的環境下,依然能夠保持單例模式的正確性。