单例模式
说明
一个类有且仅有一个实例,并且自行实例化向整个系统提供。单例模式即保证整个系统中某个类只能有一个实例
特点
单例类有且仅有一个实例
单例类必须只能自己创建自己的唯一实例
单例类必须给所有其他对象提供这一实例
实现角度看单例模式
构造函数私有化
类中包含本类静态化私有成员变量
类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
优缺点
优点
实例控制:单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
灵活:类控制了实例化过程,所以类可以灵活更改实例化过程。
缺点
开销:虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
开发人员混淆:使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
几种单例的实现方式
懒汉式:只在第一次调用时进行初始化操作。
缺点:线程不安全的,多线程的情况下会出现多个实例
public class SingleTon {
// 静态实例变量,直接初始化
private static SingleTon instance = new SingleTon();
// 私有化构造函数
private SingleTon() {
}
// 静态public方法,向整个应用提供单例获取方式
public static SingleTon getInstance() {
return instance;
}
}
改进1
使用synchronized关键字进行限制。synchronized关键字说明:https://blog.csdn.net/luoweifu/article/details/46613015
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
改进二:
双重检查+synchronized+ volatile机制:在只在第一次进入时进行实例化
volatile:https://www.cnblogs.com/shan1393/p/8999683.html
// 静态实例变量加上volatile
private static volatile SingleTon instance;
// 私有化构造函数
private SingleTon() {
}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
改进三:
通过静态类部类初始化的方式,实现单例模式。满足线程安全的要求。
public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
饿汉式
public class SingleTon {
// 静态实例变量,直接初始化
private static SingleTon instance = new SingleTon();
// 私有化构造函数
private SingleTon() {
}
// 静态public方法,向整个应用提供单例获取方式
public static SingleTon getInstance() {
return instance;
}
}
常用场景:
思考:单例模式常使用在频繁需要创建和销毁对象的地方,经典场景是Dao层的使用为什么没看单例模式的设计?
项目使用spring对bean进行管理,而@resource和@Autowired等注解默认是都是单例模式的。注:注入的bean,可以配置成多例模式。
思考:单例模式的service中怎么使用多例模式的成员变量?
https://blog.csdn.net/yansong_8686/article/details/39326581