老規(guī)矩,看例子
public class LazySingleton {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Singleton.getInstance();
}
};
for (int i = 0; i < 20; i++) {
Thread thread = new Thread(runnable);
thread.start();
}
}
}
class Singleton{
private static Singleton instance = null;
public Singleton(){
System.out.println("實(shí)例化了一個(gè)對象");
}
public static Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
image.png
你變了;蛭琛K砀唷圾浅!這不是我要的單例G扔摺0⑾恕伴逸!
這是因?yàn)椋?br>
我們先假設(shè)第一個(gè)線程成功執(zhí)行了這段代碼陨溅。
if (instance == null)
與此同時(shí)第x個(gè)線程呆馁,可能是5678910...搶到了cpu資源并執(zhí)行了
if (instance == null)
此時(shí)纵搁,第一個(gè)線程和第x個(gè)線程都通過了條件判斷岳悟,當(dāng)他們得到cpu資源后繼續(xù)執(zhí)行下面的代碼,因此會(huì)創(chuàng)建出多個(gè)實(shí)例派桩。
怎么辦构诚?怎么讓它回心轉(zhuǎn)意?
public static synchronized Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
在getInstance()方法上加個(gè)同步鎖就好啦铆惑,修改后的運(yùn)行結(jié)果:
image.png