JAVA设计模式之老生常谈的单例模式

** 类型:**它是一种创建类模式。
在平时开发的时候,无论是自己写还是看别人的代码,可能随时都会看到单例模式。可能有的人都写得不爱了。但是我还是想根据我的见解来说说它。
单例模式就是确保一个类只有一个实例,并提供一个访问它的全局访问点。单例模式写法有好几种。

  • 饿汉式:private static Singleton uniqueInstance = new Singleton();
  • 懒汉式: private static Singleton uniqueInstance = null;

Java里面实现的单例是一个虚拟机的范围。因为装载类的功能是虚拟机的,所以一个虚拟机在通过自己的ClassLoader装载饿汉式实现单例类的时候就会创建一个类的实例。
懒汉式单例有延迟加载和缓存的思想。

懒汉式单例

//懒汉式单例类.在第一次调用的时候实例化自己   
public class Singleton {  
    private Singleton() {}  
    private static Singleton single=null;  
    //静态工厂方法   
    public static Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
    }  
}  

饿汉式单例

//饿汉式单例类.在类初始化时,已经自行实例化   
public class Singleton1 {  
    private Singleton1() {}  
    private static final Singleton1 single = new Singleton1();  
    //静态工厂方法   
    public static Singleton1 getInstance() {  
        return single;  
    }  
}  

饿汉式与懒汉式的区别

  • 懒汉式是典型的时间换空间,饿汉式是典型的空间换时间
  • 不加同步的懒汉式是线程不安全的。比如,有两个线程,一个是线程A,一个是线程B,它们同时调用getInstance方法,就可能导致并发问题。饿汉式是线程安全的,因为虚拟机保证只会装载一次,在装载类的时候是不会发生并发的。

如何保证懒汉式的同步问题

  • 1.同步方法
public static synchronized Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
} 

但这样会降低整个访问的速度,而且每次都要判断。可以用双重检查加锁。

  • 2.双重检查加锁
    双重加锁机制,指的是:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法过后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。进入同步块后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例。这是第二重检查。
    双重加锁机制的实现会使用一个关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。
public class Singleton {

    /**
     * 对保存实例的变量添加volitile的修饰
     */
    private volatile static Singleton instance = null;
    private Singleton(){

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

单元素的枚举类型实现单例

根据《Effective Java第二版》中的说法,单元素的枚举类型已经成为实现Singleton的最佳方法。

public enum Singleton  {   
 singleton; 
   private Singleton () {    }
}

如有不妥,欢迎指出。哈哈哈哈

    原文作者:扈扈哈嘿
    原文地址: https://www.jianshu.com/p/e1617c47491b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞