我们知道单例模式分为饿汉模式(直接创建对象)和懒汉模式(延迟加载)
单例模式-懒汉模式在并发的情况下,会导致创建出多个对象的情况。
如下图所示,单例模式-懒汉模式创建了两个实例
下面是代码
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();
这样保证了类加载时创建一次