设计模式----单例模式
前言
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
一、饿汉式
饿汉单例模式加载方式:在被加载时就将自己实例化(推荐使用)
优点:保证线程安全;在类加载的同时已经创建好一个静态对象,调用时反应速度快
缺点:资源效率不高。
class Singleton {
//私有化构造器
private Singleton() {
}
//内部创建对象实例
private final static Singleton instance = new Singleton();
//对外公有的静态方法
public static Singleton getInstance() {
return instance;
}
}
二、懒汉式
懒汉单例模式加载方式:在第一次引用的时候才会将自己实例化
Singleton类,定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例。
优点: 避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。
缺点: 懒汉式在单个线程中没有问题,但多个线程同事访问的时候就可能同事创建多个实例,而且这多个实例不是同一个对象,虽然后面创建的实例会覆盖先创建的实例,但是还是会存在拿到不同对象的情况。解决这个问题的办法就是加锁synchonized,第一次加载时不够快,多线程使用不必要的同步开销大。
class Singleton { //线程不安全
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
三、双重检测
这里就是处理懒汉式在多线程中可能获取不到同一个实例的情况
优点:资源利用率高,不执行getInstance()就不被实例,可以执行该类其他静态方法
缺点:第一次加载时反应不快,由于java内存模型一些原因偶尔失败
class Singleton { //双重检查
private static volatile Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(instance == null) { //判断是否实例化
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance; //否则直接return
}
}
四、静态内部类
优点:资源利用率高,不执行getInstance()不被实例,可以执行该类其他静态方法
缺点:第一次加载时反应不够快,可通过反射和反序列化进行更改
class Singleton {
private static volatile Singleton instance;
private Singleton() {}
//静态内部类,包含一个静态属性:Singleton
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
//对外公有的静态方法,直接返回SingletonInstance.INSTANCE
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
总结
一般采用饿汉式,若对资源十分在意可以采用静态内部类