zoukankan      html  css  js  c++  java
  • Java多线程下单例

    /*
    多线程下的单例
    
    */
    
    //饿汉式
    class Single
    {
        private static final Single s = new Single();
        private Single(){}
        public static Single getInstance()
        {
            return s;
        }
    }
    /*
    懒汉式
    
    加入同步为了解决多线程安全问题。
    
    加入双重判断是为了解决效率问题。
    */
    
    class Single
    {
        private static Single s = null;
        private Single(){}
        public static Single getInstance()
        {
            if(s==null)
            {
                synchronized(Single.class)        
                {
                    if(s==null)
            //                -->0 -->1
                        s = new Single();
                }
            }
            return s;
        }
    }
    class  SingleDemo
    {
        public static void main(String[] args) 
        {
            System.out.println("Hello World!");
        }
    }

    一种更好的单例实现方法

           饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。可见,无论是饿汉式单例还是懒汉式单例都存在这样那样的问题,有没有一种方法,能够将两种单例的缺点都克服,而将两者的优点合二为一呢?答案是:Yes!下面我们来学习这种更好的被称之为Initialization Demand Holder (IoDH)的技术。

          在IoDH中,我们在单例类中增加一个静态(static)内部类,在该内部类中创建单例对象,再将该单例对象通过getInstance()方法返回给外部使用,实现代码如下所示:

    //Initialization on Demand Holder  
    class Singleton {  
        private Singleton() {  
        }  
          
        private static class HolderClass {  
                private final static Singleton instance = new Singleton();  
        }  
          
        public static Singleton getInstance() {  
            return HolderClass.instance;  
        }  
          
        public static void main(String args[]) {  
            Singleton s1, s2;   
                s1 = Singleton.getInstance();  
            s2 = Singleton.getInstance();  
            System.out.println(s1==s2);  
        }  
    }  

    编译并运行上述代码,运行结果为:true,即创建的单例对象s1和s2为同一对象。由于静态单例对象没有作为Singleton的成员变量直接实例化,因此类加载时不会实例化Singleton,第一次调用getInstance()时将加载内部类HolderClass,在该内部类中定义了一个static类型的变量instance,此时会首先初始化这个成员变量,由Java虚拟机来保证其线程安全性,确保该成员变量只能初始化一次。由于getInstance()方法没有任何线程锁定,因此其性能不会造成任何影响。

          通过使用IoDH,我们既可以实现延迟加载,又可以保证线程安全,不影响系统性能,不失为一种最好的Java语言单例模式实现方式(其缺点是与编程语言本身的特性相关,很多面向对象语言不支持IoDH)。

  • 相关阅读:
    【题解】直线交点数
    【题解】[TJOI2010] 阅读理解
    清北学堂 2020 国庆J2考前综合强化 Day7
    清北学堂 2020 国庆J2考前综合强化 Day6
    清北学堂 2020 国庆J2考前综合强化 Day5
    清北学堂 2020 国庆J2考前综合强化 Day4
    清北学堂 2020 国庆J2考前综合强化 Day3
    test
    清北学堂 2020 国庆J2考前综合强化 Day2
    清北学堂 2020 国庆J2考前综合强化 Day1
  • 原文地址:https://www.cnblogs.com/xiarongjin/p/8309020.html
Copyright © 2011-2022 走看看