前言
使用单例模式解决线程安全问题。
饿汉式的单例模式
public class Single1 {
private static Single1 single1=new Single1();
private Single1(){
}
public static Single1 getInstance(){
return single1;
}
}
- 优点:
饿汉方式,直接将对象属性上创建,static,直接被内存,程序不退让。没有线程安全问题。 - 缺点:
唯一的缺陷就是不管使用与否,内存都要占据,而且不会释放
懒汉式的单例模式
public class Single2 {
private static Single2 single2;
private Single2(){
}
public static Single2 getInstance(){
if(null ==single2){
single2=new Single2();
}
return single2;
}
}
- 优点:
在首次调用时,产生对象。在需要使用对象的时候,再去创建对象,解决掉了饿汉式的内存占用问题。 - 缺点:
不适合高并发场景,非线程安全的。
DCL(double check lock)懒汉式解决线程安全问题
public class Single3 {
/**
* 1.内存可见性
* 2.禁止指令重排序
*/
private static volatile Single3 single3;
private Single3(){
}
public static Single3 getInstance(){
if(null ==single3){
synchronized (Single3.class) {
if(null==single3){
single3=new Single3();
}
}
}
return single3;
}
}
如果要解决线程安全问题,需要加锁处理。
方式一: 直接在方法上加锁,粗暴解决线程安全问题。
方法二:在创建对象的代码上加锁(锁的范围小,效率高)
但是如果采用这种方法,需要进行两次判空。
需要注意指令重排序。