单例模式

作者: 降龙_伏虎 | 来源:发表于2019-06-19 10:46 被阅读0次

单例模式(Singleton Pattern)

是指确保一个类在任何情况下都绝对只有一个实例
私有化构造方法,属于创建型模式(结构型模式/行为型模式)

1.饿汉式单例

不管使用使用到,在类加载是进行创建
缺点:浪费空间
public class HungrySingleton{
    //私有静态不可覆盖变量
    private static final HungrySingleton hungrySingleton; 
    
    //类加载时创建类实例
    static{
        hungrySingleton = new HungrySingleton();
    }
    
    //私有化构造方法
    private HungrySingleton(){}
    
    //静态获取实例方法
    public static HungrySingleton getInstace(){
        return hungrySingleton;
    }
}

2.懒汉式单例

类加载是并不初始化,第一次使用时进行初始化
public class LazySingleton{
    //私有静态变量,默认为空
    private static  LazySingleton lazySingleton=null; 
    
    //私有化构造方法
    private HungrySingleton(){}
    
    //静态获取实例方法,线程不安全实例可能会多次被创建
    public static LazySingleton getInstace(){
        if(lazySingleton == null){
            lazySingleton = new lazySingleton();
        }
        return lazySingleton;
    }
}

3.注册式单例

即:内部类模式单例(性能最优)
public class LazyInnerClassSingleton{

    //私有化构造方法
    private LazyInnerClassSingleton(){
        //防止反射破解
        if(LazyHolder.LAZY != null){
            throw new Exception("不允许构建多个实例");
        }
    }
    
    //静态获取实例方法,线程安全
    //①懒汉式加载
    //②LazyHoler中的逻辑,当getInstace被调用时候才知晓
    //③巧妙的运用了内部类的特性,JVM底层逻辑.完美的避免了线程安全问题
    public static fianl LazyInnerClassSingleton getInstace(){
       return LazyHolder.LAZY;
    }
    //防止序列化->反序列化对象破解单例
    private Object readResolve(){
        return LazyHolder.LAZY
    }
    
    //内部类
    private static  class LazyHolder{
        private static  final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();
    }
}

//反射破解
public class Test{
    public static void main(String[] args0){
        try{
            Class<?> clazz = LazyInnerClassSingleton.class;
            java.lang.reflect.Conotructor c = clazz.getDeclaredConotructor(null);
            c.setAccessible(true);
            c.newInstance();
        }catch(Exception e){
            e.printStackTrace();
        }

    }   
}

3.1枚举式(注册式的一种)

/**
 * Description:数据库连接(被单例对象)
 *
 * @date 2019-05-09 16:23
 */

public class DBConnection {
}

/**
 * Description:数据源枚举
 *
 * @date 2019-05-09 16:10
 */

public enum DataSourceEnum {

    DATASOURCE;

    private DBConnection dbConnection;

    public DBConnection getDbConnection() {
        return dbConnection;
    }

    public static DataSourceEnum getInstance(){
        return DATASOURCE;
    }

    DataSourceEnum() {
        this.dbConnection = new DBConnection();
    }
}

/**
 * Description:测试
 *
 * @date 2019-05-09 16:14
 */

public class Test {
    public static void main(String[] args) {
        DBConnection con1 = DataSourceEnum.DATASOURCE.getDbConnection();
        DBConnection con2 = DataSourceEnum.DATASOURCE.getDbConnection();
        System.out.println(con1 == con2);
    }
}

原理

3.2容器式单例

① 私有化构造方法

②定义线程安全的容器(ConcurrentMap)

③获取对象时,先从容器内取,存在容器内直接返回;不出存在通过反射获取对象放入容器后进    行返回,注意线程安全问题,需要解决

3.3.ThreadLocal单例

伪线程安全:全局线程不安全,线程内线程安全
public class Apple{

    private Apple(){}
    
    private static final ThreadLocal<Apple> threadLocalInstance = new ThreadLocal<Apple>(){
        @Override
        protected Apple initiaValue(){
            return new Apple();
        }
    }
    
    public static Apple getInstance(){
        threadLocalInstance.get();
    }
}

相关文章

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • 设计模式之单例模式详解

    设计模式之单例模式详解 单例模式写法大全,也许有你不知道的写法 导航 引言 什么是单例? 单例模式作用 单例模式的...

  • Telegram开源项目之单例模式

    NotificationCenter的单例模式 NotificationCenter的单例模式分析 这种单例模式是...

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • 单例模式

    单例模式1 单例模式2

  • java的单例模式

    饿汉单例模式 懒汉单例模式

网友评论

    本文标题:单例模式

    本文链接:https://www.haomeiwen.com/subject/ucshqctx.html