美文网首页
Java 单例模式

Java 单例模式

作者: 东方灵龙 | 来源:发表于2016-12-01 11:35 被阅读24次

    线程安全的单例模式的几种实现方法分享
    线程安全的单例模式实现有几种思路,个人认为第2种方案最优雅

    • 饿汉式
    • 借助内部类
    • 普通加锁解决
    • 双重检测
      但要注意写法,如果单体模式继续扩展为N元单体模式,那就是对象池模式了

    1、饿汉式单例

    public class Singleton {
       private final static Singleton INSTANCE = new Singleton();
       private Singleton() { }
       public static Singleton getInstance() {
          return INSTANCE;
       }
    }
    

    2、借助内部类,相对来说,这个比较省事,不过也因为是内部类,当前对象的持有也需要注意。

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

    3、懒汉模式下的几种情况

    • 3.1 普通加锁模式,虽然解决了线程安全问题,但是每个线程调用getInstance都要加锁
    public class Singleton {
       private static Singleton instance = null;
       private Singleton() {}
       public static synchronized Singleton getInstance() {
          if(instance == null) {
             instance = new Singleton();
          }
          return instance;
       }
    }
    
    • 3.2 双重检测,但要注意写法,由于指令重排序问题的问题,所以这种写法比较安全可靠一些
    public class Singleton {
       private static Singleton instance = null;
       private Singleton() { }
       public static Singleton getInstance() {
          if(instance == null) {
             synchronzied(Singleton.class) {
                Singleton temp = instance;
                if(temp == null) {
                   temp = new Singleton();
                   instance = temp
                }
             }
          }
          return instance;
       }
    }
    
    • 3.3 双重检测,使用volatile修饰,这样的话就可以确保instance = new Singleton(); 对应的指令不会重排序
    public class Singleton {
       private static volatile Singleton instance = null;
       private Singleton() {}
       public static Singleton getInstance() {
          if(instance == null) {
             synchronzied(Singleton.class) {
                if(instance == null) {
                   instance = new Singleton();
                }
             }
          }
          return instance;
       }
    }
    

    3.4 不要写出以下的代码,虽然在不是超级频繁调用的情况下以下代码也能和3.3的效果一样的正确运行
    3.4 不要写出以下的代码,虽然在不是超级频繁调用的情况下以下代码也能和3.3的效果一样的正确运行
    3.4 不要写出以下的代码,虽然在不是超级频繁调用的情况下以下代码也能和3.3的效果一样的正确运行

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

    相关文章

      网友评论

          本文标题:Java 单例模式

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