Java单例模式

  1. 饿汉式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //饿汉式单例类,在类初始化时,已经自行实例化
    public class Singleton1 {
    //私有的默认构造方法
    private Singleton1(){}
    //已经自行实例化
    private static final Singleton1 single = new Singleton1() ;
    //静态工厂方法
    private static Singleton1 getInstance(){
    return single ;
    }
    }
  1. 懒汉式单例类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //懒汉式单例类,在第一次调用的时候实例化
    public class Singleton2 {
    //私有的默认构造方法
    private Singleton2(){}
    //注意,这里没有final
    private static Singleton2 single = null ;
    //静态工厂方法,如果不加synchronized线程不安全
    public synchronized static Singleton2 getInstance() {
    if(single == null ){
    single = new Singleton2() ;
    }
    return single ;
    }
    }
  2. 登记式单例类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public class RegistSingleton {
    //用ConcurrentHashMap来维护映射关系,这是线程安全的
    public static final Map<String,Object> REGIST=new ConcurrentHashMap<String, Object>();
    static {
    //把RegistSingleton自己也纳入容器管理
    RegistSingleton registSingleton=new RegistSingleton();
    REGIST.put(registSingleton.getClass().getName(),registSingleton);
    }
    private RegistSingleton(){}
    public static Object getInstance(String className){
    //如果传入的类名为空,就返回RegistSingleton实例
    if(className==null)
    className=RegistSingleton.class.getName();
    //如果没有登记就用反射new一个
    if (!REGIST.containsKey(className)){
    //没有登记就进入同步块
    synchronized (RegistSingleton.class){
    //再次检测是否登记
    if (!REGIST.containsKey(className)){
    try {
    //实例化对象
    REGIST.put(className,Class.forName(className).newInstance());
    } catch (InstantiationException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    }
    }
    }
    //返回单例
    return REGIST.get(className);
    }
    }

总结

java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

0%