单例模式

什么是单例模式?

  有些对象我们只需要一个,比如配置文件、工具类、线程池、缓存、日志对象等,如果创造多个实例,就会导致许多问题,比如占用过多资源,不一致的结果等。
  使用单例模式能够保证整个应用中有且只有一个实例。

单例模式的写法

1. 饿汉模式(推荐)

代码:

public class Singleton {
    //1.将构造方法私有化,不允许外部直接创建对象
    private Singleton(){        
    }
    //2.创建类的唯一实例,使用private static修饰
    private static Singleton instance=new Singleton();
    //3.提供一个用于获取实例的方法,使用public static修饰
    public static Singleton getInstance(){
        return instance;
    }
}

访问方式:Singleton instance = Singleton.getInstance();
  饿汉模式的特点是加载类时比较慢,但运行时获取对象的速度比较快(初始化对象创建单例),因为是初始化就创建了实例,易造成资源浪费,线程安全。

2.懒汉模式(线程不安全,不推荐)

代码:

public class Singleton {
    //1.将构造方式私有化,不允许外边直接创建对象
    private Singleton(){
    }
    //2.声明类的唯一实例,使用private static修饰
    private static Singleton instance;
    //3.提供一个用于获取实例的方法,使用public static修饰
    public static Singleton getInstance(){
        if(instance==null){
            instance=new Singleton();
        }
        return instance;
    }
}

访问方式:Singleton instance = Singleton.getInstance();
  懒汉模式的特点是加载类时比较快(加载类时new),但运行时获取对象的速度比较慢,线程不安全。既然是线程不安全的,那么就需要改进为线程安全形式的,经过大神们的探索,下面是其改进结果。

3.双重校验锁懒汉模式(推荐)

代码:

public class Singleton {  
    /** 
     * 懒汉式变种,属于懒汉式中最好的写法,保证了:延迟加载和线程安全 
     */  
    private static Singleton instance=null;  

    private Singleton() {};  

    public static Singleton getInstance(){  
         if (instance == null) {    
              synchronized (Singleton.class) {    
                  if (instance == null) {    
                      instance = new Singleton();    
                  }    
              }    
          }    
          return instance;    
    }  
}  

访问方式:Singleton instance = Singleton.getInstance();
  Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,我们进行了两次if (instance== null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if (instance== null),直接return实例化对象。
  优点:线程安全;延迟加载;效率较高。

4.内部类方式(推荐)

代码:

public class Singleton{  
    private Singleton() {};  
    //内部类
    private static class SingletonHolder{  
        private static Singleton instance=new Singleton();  
    }  
    public static Singleton getInstance(){  
        return SingletonHolder.instance;  
    }  
}  

访问方式:Singleton instance = Singleton.getInstance();
  这种方式和饿汉式机制类似,两者都是采用了类装载的机制来保证初始化实例时只有一个线程。但是饿汉式是类被装载的时候就会实例化,没有lazy-loading的作用,而静态内部类方式在singleton类被装载时并不会立即实例化,而是需要实例化时,调用getInstance()方法,才会装载SingletonHolder类,从而完成Singleton的实例化。类的静态属性只会在第一次加载类的时候初始化,jvm保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
  优点:避免了线程不安全;延迟加载;效率高。

5.枚举方式(推荐)

代码:

public enum SingletonEnum {  
     instance;   
     private SingletonEnum() {}  
     public void method(){  
     }  
}  

访问方式:SingletonEnum.instance.method();
  在这里SingletonEnum.instance这里的instance即为SingletonEnum类型的引用,所以得到它就可以调用枚举中的方法了。
  借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值