单例模式(懒汉饿汉同步锁static枚举)实现
Posted soul-wonder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式(懒汉饿汉同步锁static枚举)实现相关的知识,希望对你有一定的参考价值。
使用前提:
需要频繁的进行创建和销毁的对象,创建对象时耗时过多或耗费资源过多
三要素:
- 1、构造方法私有化;
- 2、实例化的变量引用私有化;
- 3、获取实例的方法共有。
1.饿汉式单例
弊端:在类装载的时候就完成实例化
/** * 饿汉式单例 * * @author Wonder * @history create Wonder 2018年10月24日 上午9:55:32 * @version 1.0 */ public class Singleton1 { private Singleton1() { }// 1私有化构造 private final static Singleton1 singleton1 = new Singleton1();// 2实例化 public static Singleton1 getInstance() {// 3对外提供 return singleton1; } }
2.懒汉式单例
弊端:多线程环境下会产生多个single对象,线程不安全
/** * 懒汉式单例 * 多线程环境下会产生多个single对象 * * @author Wonder * @history create Wonder 2018年10月24日 上午10:17:59 * @version 1.0 */ public class Singleton2 { private Singleton2() { }// 1私有化构造 private static Singleton2 singleton2 = null;// 延迟实例 public static Singleton2 getInstance() { if (singleton2 == null) { singleton2 = new Singleton2(); } return singleton2; } }
3.懒汉式单例(synchronized同步锁)
弊端:效率低
同步方法的方式:获取实例时,每次都要执行同步方法,效率太低
同步代码块的方式:可能多个线程同时进入if判断,实际页无法起到线程同步的作用
/** * 懒汉式单例 只对需要锁的代码部分加锁 * * @author Wonder * @history create Wonder 2018年10月24日 上午10:17:59 * @version 1.0 */ public class Singleton4 { private Singleton4() { }// 1私有化构造 private static Singleton4 single = null;// 延迟实例 public static Singleton4 getInstance() { if (single == null) { synchronized (Singleton4.class) { single = new Singleton4(); } } return single; } }
4.双重检查
1.使用volatile关键字,保证多线程下的可见性
为什么要使用volatile:https://www.cnblogs.com/damonhuang/p/5431866.html
2.进行了两次if (singleton == null)检查,如果为null,同步代码块,创建实例,否则直接返回singleton实例
public class Singleton { private static volatile Singleton singleton; private Singleton() {} public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
5.静态代码块和静态内部类
静态代码块的方式
public class Singleton5 { private Singleton5() { }// 1私有化构造 private static Singleton5 single = null;// 延迟实例 // static静态代码块 static { single = new Singleton5(); } public static Singleton5 getInstance() { return single; } }
静态内部类方式更优(懒加载)
静态内部类方式在Singleton类被装载时并不会立即实例化
public class Singleton { private Singleton() {} private static class SingletonInstance { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonInstance.INSTANCE; } }
6.枚举实现
简单枚举方式:
public enum Singleton { INSTANCE; public void whateverMethod() { } }
优化:内部枚举类
public class SingletonFactory { // 内部枚举类 private enum EnmuSingleton { SINGLETON; private Singleton6 single; // 枚举类的构造方法在类加载是被实例化 private EnmuSingleton() { single = new Singleton6(); } public Singleton6 getInstance() { return single; } } public static Singleton6 getInstance() { return EnmuSingleton.SINGLETON.getInstance(); } } class Singleton6 { public Singleton6() { } }
以上是关于单例模式(懒汉饿汉同步锁static枚举)实现的主要内容,如果未能解决你的问题,请参考以下文章
Java 设计模式 -- 单例模式的实现(饿汉式枚举饿汉式懒汉式双检锁懒汉式内部类懒汉式)jdk 中用到单例模式的场景DCL实现单例需用volatile 修饰静态变量
单例模式的5种实现方式(懒汉模式饿汉模式双重锁模式静态内部类模式枚举模式)