本文目录导读:
单例模式简介
单例模式(Singleton Pattern)是一种常用的软件设计模式,它保证一个类仅有一个实例,并提供一个访问该实例的全局访问点,这样可以确保在一个程序中,某个类的实例在任何时候都只有一个,从而避免了多线程环境下的数据不一致问题。
单例模式的实现原理
1、懒汉式:在第一次调用时实例化对象,实现了延迟加载,但需要考虑线程安全问题。
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
2、饿汉式:在类加载时就完成了初始化,避免了线程同步问题,但可能导致资源浪费。
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
3、双重检查锁定(DCL):在懒汉式的基础上,通过双重检查锁定机制,既保证了线程安全,又实现了懒加载。
public class Singleton { private volatile static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
4、静态内部类:利用静态内部类的特性,实现了懒加载,同时保证了线程安全。
public class OuterClass { private static class InnerClass extends Thread implements Serializable { private static final long serialVersionUID = -8497643500292891256L; private static InnerClass instance = new InnerClass(); private boolean isAlive = true; private String name = "InnerClass"; private int count = 0; //计数器,防止多线程同时调用getInstance方法创建多个实例,这里使用了一个静态变量count来控制,当count==0的时候才创建新的对象,当count>0的时候表示已经存在对象,直接返回这个对象即可,这种方式也被称为“双检锁”,如果不加这个判断的话,可能会出现两个线程同时进入if (instance == null),然后各自创建一个新的实例的情况,这样的话虽然也能达到单例的效果,但是却违背了单例的原则——一个类只能有一个实例,所以在这里加上了count的判断,这样就可以保证在多线程环境下只创建一个实例,而且由于使用了synchronized关键字对代码块进行了加锁,所以也可以保证在多线程环境下的安全性,当然了,这里只是为了说明问题才加上的这个判断,实际上我们完全可以去掉这个判断,因为在Java中synchronized关键字是能保证线程安全的,而且在多核CPU下,由于每个核心都有自己的一套内存空间,所以synchronized关键字并不能保证线程安全,但是在单核CPU下,由于所有的指令都是在同一个内存空间中执行的,所以synchronized关键字就能保证线程安全了,不过这里为了讲解方便还是加上了这个判断。