通用源码:
/** * 单例模式通用源代码 - [ 饿汉式单例 ] * * Singleton 类为单例类,通过使用 private 的构造器确保了在一个应用中只产生一个实例,并且是自行实例化. * * @author wenlong * @date 2019/05/25 23:25 */ public class Singleton { private static final Singleton SINGLETON = new Singleton(); private Singleton() { } public static Singleton getSingleton() { return SINGLETON; } public static void doSomething() { System.out.println("Do something!"); } }上述单例有的地方称为饿汉式单例。 下述这种被称为懒汉式单例:
/** * 单例模式实现 - 懒汉式单例 * * @author *** * @date 2019/05/26 11:19 */ public class Singleton2 { private static Singleton2 singleton2 = null; private Singleton2() { // 私有构造器 } public static synchronized Singleton2 getInstance() { if (singleton2 == null) { singleton2 = new Singleton2(); } return singleton2; } }具体实现:
/** * 有上限的多例模式 - 单例模式的扩展 * * @author wenlong * @date 2019/05/26 11:42 */ public class LimitNumOfInstances { // 定义最多能产生的实例数量 private static int maxNumOfInstances = 3; /** * 定义对象的私有属性 */ private String name; /** * 定义容器,容纳所有的实例 */ private static List<LimitNumOfInstances> limitNumOfInstancesList = new ArrayList<>(); /** * 当前实例的编号 */ private static int indexOfInstance = 0; private LimitNumOfInstances() { } private LimitNumOfInstances(String name) { this.name = name; } // 生成所有对象 static { for (int i = 0;i < maxNumOfInstances;i++) { limitNumOfInstancesList.add(new LimitNumOfInstances("实例-" + i)); } } public static LimitNumOfInstances getInstance() { Random random = new Random(); // 随机获取一个实例 indexOfInstance = random.nextInt(maxNumOfInstances); return limitNumOfInstancesList.get(indexOfInstance); } /** * 验证 */ public void getInfo() { System.out.println(this.name); } }验证:
/** * @author wenlong * @date 2019/05/26 12:17 */ public class Test { public static void main(String[] args) { for (int i = 0;i < 5;i++) { LimitNumOfInstances randonOne = LimitNumOfInstances.getInstance(); randonOne.getInfo(); } } }测试结果:
1.饿汉式(静态代码块)
/** * 单例模式 - 饿汉式(静态代码块) * * @author wenlong * @date 2019/05/26 16:27 */ public class Singleton3 { private static Singleton3 instance; static { instance = new Singleton3(); } private Singleton3() {} public static Singleton3 getInstance() { return instance; } }2.懒汉式(线程不安全)
/** * 单例模式实现 - 懒汉式单例 - 线程不安全 * * @author *** * @date 2019/05/26 11:19 */ public class Singleton2 { private static Singleton2 singleton2; private Singleton2() { // 私有构造器 } public static Singleton2 getInstance() { if (singleton2 == null) { singleton2 = new Singleton2(); } return singleton2; } }3.懒汉式(线程安全 - 同步代码块)
/** * 懒汉式单例 - 同步代码块 * * @author wenlong * @date 2019/05/26 16:51 */ public class Singleton4 { private static Singleton4 instance; private Singleton4() {} public static Singleton4 getInstance() { if (instance == null) { synchronized(Singleton4.class) { instance = new Singleton4(); } } return instance; } }该写法虽然是线程安全的,但是在多线程环境下还是有可能产生多个实例。不可用。
4.懒汉式 - 双重检查【推荐使用】
/** * 单例模式 - 懒汉式 - 同步代码块 - 双重检查 * 优点:线程安全;延迟加载;效率较高。 * * @author wenlong * @date 2019/05/26 17:01 */ public class Singleton5 { private static volatile Singleton5 instance; private Singleton5() {} public Singleton5 getInstance() { if (instance == null) { synchronized(Singleton5.class) { if (instance == null) { instance = new Singleton5(); } } } return instance; } }5.静态内部类【推荐使用】
/** * 单例模式 - 静态内部类 * * @author wenlong * @date 2019/05/26 17:10 */ public class Singleton6 { private Singleton6() {} /** * 静态内部类 */ private static class SingletonInstance { private static final Singleton6 INSTANCE = new Singleton6(); } public static Singleton6 getInstance() { return SingletonInstance.INSTANCE; } }这种方式跟饿汉式方式采用的机制类似,但又有不同。两者都是采用了类装载的机制来保证初始化实例时只有一个线程。不同的地方在饿汉式方式是只要Singleton类被装载就会实例化,没有Lazy-Loading的作用,而静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时,调用 getInstance 方法,才会装载 SingletonInstance 类,从而完成 Singleton 的实例化。
类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM 帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
优点:避免了线程不安全,延迟加载,效率高。
6.单例模式 - 枚举【推荐使用】
/** * 单例模式 - 枚举 * * @author wenlong */ public enum Singleton7 { /** * 单例模式 - 枚举 */ INSTANCE; public void whateverMethod() { System.out.println("哈哈哈"); } }