设计模式之单例模式

单例模式-singleton

意图

保证一个类只能有一个实例,而且自行实例化并向整个系统提供这个实例,避免频繁创建对象,节约内存

背景

类加载

如果类还没有被加载:

  • 先执行父类的静态代码块和静态变量初始化,静态代码块和静态变量的执行顺序跟代码中出现的顺序有关。
  • 执行子类的静态代码块和静态变量初始化。
  • 执行父类的实例变量初始化
  • 执行父类的构造函数
  • 执行子类的实例变量初始化
  • 执行子类的构造函数

同时,加载类的过程是线程私有的,别的线程无法进入。

如果类已经被加载:

静态代码块和静态变量不在重复执行,再创建类对象时,只执行与实例相关的变量初始化和构造方法。

单例模式的实现

普通的懒汉式(非线程安全)

public class Single{
    private static Single singleton = null;
    
    public static Single getInstance(){
        if(singleton == null)
        {
            singleton = new Single();
		}
        return singleton;
    }  
}

多线程访问单例

后果

造成多个单例创建,违背了只有一个单例变量的目的。

解决办法

立即创建/饿汉式

public class Single
{
    private static Single singleton = new single();//立即创建,线程安全

    public static Single getInstance()
    {
        return singleton;
    }
}

同步懒汉式

public class Single{
    private static Single singleton = null;
    
    public static synchronized Single getInstance(){//synchronized方法同步
        if(singleton == null)
        {
            singleton = new Single();
        }
        return singleton;
}  

}

双重检查懒汉式锁

public class Single
{
    private volatile static Single singleton = null;//关键字volatile,禁止指令重排序,防止空指针异常(结合并发思考)
    
    public static Single getInstance()
    {
        if(singleton == null){
			synchronized (Single.class)//线程锁,创建不允许中断,synchronized代码块同步
            {
                if(singleton == null)
                    singleton = new Single();                    
			}
        }
        return singleton;
    }
}

静态内部类

public class Single {

    private static class SingleInstance {
        private static final Single INSTANCE = new Singleton();
    }

    public static Single getInstance() {
        return SingleInstance.INSTANCE;
    }

}

参考资料:Head First Design Patterns

posted @ 2021-07-04 23:47  kirk9909  阅读(40)  评论(0)    收藏  举报