一、什么是单例模式
JAVA中有23种设计模式,其中单例模式是最常用的一种,也是最容易写的一种。单例模式是一种对象创建模式,产生一个对象的具体实例(只能有一个实例),在日常的开发中我们可以通过对开发人员要求来实现这种效果而不必用单例模式,但是有些特殊的情况下这种规定毫无所用所以我们要用到单例来规避这种现象的出现。
综上所述单例模式就是确保一个类只有一个实例,必须自己创建自己的唯一实例,并且给所有其他对象提供这一实例对象。
二、单例模式优缺点
(1)优点
1.对实现的严格访问控制:确保所有对象都访问唯一实例;
2.只有一个实例,节省系统资源;
3.避免对共享资源的多重占用;
(2)缺点
1.扩展性不强,单例模式没有抽象层;
2.根据实际情况运用单例模式,不可滥用,例如:为了节省资源将数据库连接池对象设计为单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;
3.在一定程度上违反单一原则;
三、应用场景
1.系统要求只创建一个对象的实例;
2.资源共享的情况下,避免重复操纵导致性能损耗;
3.资源控制的情况下,方便资源的相互通信,如数据库连接池;
四、单例模式用法
单例模式主要分为三种:懒汉式,饿汉式,登记式。由于登记式J较为少见所以这里不再阐述。
(1)单线程的方式
public class Singleton {
private static Singleton instance=null;
private Singleton(){
}
public static Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
解析:在多线程的情况下,当两个线程同时运行到判断instance是否为空的if判断时,那么这两线程都会创建一个实例。
(2)懒汉式(多线程)
public class Singleton {
private static Singleton instance=null;
private Singleton(){
}
public static synchronized Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
解析:再上一种方法上加了同步锁,适用于多线程。但是每次通过getInstance方法得到singleton实例的时候都有一个试图去获取同步锁的过程。而众所周知,加锁是很耗时的。能避免则避免。
(3)饿汉式
public class Singleton {
private static Singleton instance=new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
解析:初试化静态的instance创建一次。如果我们在Singleton类里面写一个静态的方法不需要创建实例,它仍然会早早的创建一次实例。而降低内存的使用率。
缺点:没有lazy loading的效果,从而降低内存的使用率。
(4)静态内部类
public class Singleton {
private Singleton(){
}
private static class SingletonStatic{
private final static Singleton instance=new Singleton();
}
public static Singleton getInstance(){
return SingletonStatic.instance;
}
}
解析:定义一个私有的内部类,在第一次用这个嵌套类时,会创建一个实例。而类型为SingletonHolder的类,只有在Singleton.getInstance()中调用,由于私有的属性,他人无法使用SingleHolder,不调用Singleton.getInstance()就不会创建实例。
优点:达到了lazy loading的效果,即按需创建实例。
耐心之树,结黄金之果。