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)。

  • 相关阅读:
    docker 部署aps.net MVC到windows容器
    docker 搭建私有仓库 harbor
    解决关于:Oracle数据库 插入数据中文乱码 显示问号???
    ionic cordova build android error: commamd failed with exit code eacces
    cordova build android Command failed with exit code EACCES
    Xcode 10 iOS12 "A valid provisioning profile for this executable was not found
    使用remix发布部署 发币 智能合约
    区块链: 编译发布智能合约
    mac 下常用命令备忘录
    JQuery fullCalendar 时间差 排序获取距当前最近的时间。
  • 原文地址:https://www.cnblogs.com/xiarongjin/p/8309020.html
Copyright © 2011-2022 走看看