我們知道單例模式分爲餓漢模式(直接創建對象)和懶漢模式(延遲加載)
單例模式-懶漢模式在併發的情況下,會導致創建出多個對象的情況。
如下圖所示,單例模式-懶漢模式創建了兩個實例
下面是代碼
package com.design.mode.single;
/**
* @description:
* @author: HYW
* @create: 2020-01-03 08:45
*/
public class Single {
private static Single single;
private Single(){};
public static Single getInstance(){
if(single == null){
single=new Single();
}
return single;
}
String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
測試類
package com.design.mode.single;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @description:
* @author: HYW
* @create: 2020-01-03 08:48
*/
public class Demo {
public static void main(String[] args) {
ThreadPoolExecutor pool=new ThreadPoolExecutor(10,20,1000,
TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(20));
for(int i=0;i<15;i++) {
pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Single single=Single.getInstance();
System.out.println(single);
}
});
System.out.println("線程池中線程數目:"+pool.getPoolSize()+",隊列中等待執行的任務數目:"+
pool.getQueue().size()+",已執行玩別的任務數目:"+pool.getCompletedTaskCount());
}
pool.shutdown();
}
}
問題原因,如果第一次創建實例時,多個線程同時執行任務,就會導致這段代碼被多次執行
if(single == null){
single=new Single();
}
解決方式
1.雙重鎖 volatile + synchronized
volatile private static Single single;
private Single(){};
synchronized public static Single getInstance(){
if(single == null){
single=new Single();
}
return single;
}
2.餓漢模式
private static Single single=new Single();
這樣保證了類加載時創建一次