单例模式

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  1. 单例类只能有一个实例。
  2. 单例类必须自己自己创建自己的唯一实例。
  3. 单例类必须给所有其他对象提供这一实例。

饿汉模式

public class Singleton {
    //private 私有 
    private static Singleton instance = new Singleton();
    //private 私有
    private Singleton(){}
    public static Singleton getInstance(){
        return instance;
    }
}

懒汉式(非线程安全)

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

懒汉式(线程安全)

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

双重校验锁(DCL)

public class Singleton {

    /**
     * 注意此处使用的关键字 volatile,
     * 被volatile修饰的变量的值,将不会被本地线程缓存,
     * 所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。
     */
    private volatile static Singleton singleton;
    private Singleton() {
    }
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return singleton;
    }
}

静态内部类

public class Singleton { 
    private Singleton(){
    }
      public static Singleton getInstance(){  
        return SingletonHolder.sInstance;  
    }  
    private static class SingletonHolder {  
        private static final Singleton sInstance = new Singleton();  
    }  
}

使用容器

public class SingletonManager { 
  private static Map objMap = new HashMap();
  private Singleton() { 
  }
  public static void registerService(String key, Objectinstance) {
    if (!objMap.containsKey(key) ) {
      objMap.put(key, instance) ;
    }
  }
  public static ObjectgetService(String key) {
    return objMap.get(key) ;
  }
}

Volatile可以看做是轻量级的 Synchronized,它只保证了共享变量的可见性。在线程 A 修改被 volatile 修饰的共享变量之后,线程 B 能够读取到正确的值。java 在多线程中操作共享变量的过程中,会存在指令重排序与共享变量工作内存缓存的问题。

public class single {
    
    public static  void main (String[] args) {
            
        singleton sin1 = singleton.getSingle();
        singleton sin2 = singleton.getSingle();
        System.out.println(sin1 == sin2);
        
        Singleton2 sin3 = Singleton2.getInstance();
        Singleton2 sin4 = Singleton2.getInstance();
        System.out.println(sin3 == sin4);
        
        }
        
}



//饿汉式。类一加载对象就创建单例对象
class singleton{
    
    private static singleton sin = new singleton();
    
    private singleton() {};
    
    public static singleton getSingle() {
        return sin;
    }   
}


//懒汉式,即延迟加载。单例在第一次调用 getInstance() 方法时才实例化,在类加载时并不自动实例化,在需要的时候再进行加载实例。
class Singleton2 {

    private Singleton2(){}

    private static Singleton2 instance = null;

    public static Singleton2 getInstance(){
        if(instance == null){
            instance = new Singleton2();
        }
        return instance;
    }
}


//多线程处理创建单例是一起的,用排队,避免如果使用懒汉式的方式创建单例对象,那就可能会出现创建多个实例的情况,添加Synchronized实现线程安全
//不过,在多线程中很好的工作而且是线程安全的,但是每次调用 getInstance() 方法都需要进行线程锁定判断,在多线程高并发访问环境中,将会导致系统性能下降。事实上,不仅效率很低,99%情况下不需要线程锁定判断。
class Singleton3 {

    private Singleton3(){}

    private static Singleton3 instance = null;

    public static synchronized Singleton3 getInstance(){
        if(instance == null){
            instance = new Singleton3();
        }
        return instance;
    }
}


//过双重校验锁的方式进行处理。换句话说,利用双重校验锁,第一次检查是否实例已经创建,如果还没创建,再进行同步的方式创建单例对象。
class Singleton4 {

    private Singleton4(){}

    private static Singleton4 instance = null;

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


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

你可能感兴趣的:(单例模式)