zoukankan      html  css  js  c++  java
  • 单例模式的改进

      前面说过的单例模式为了避免被不同的线程创建多次,各个线程引用了不同的实例,这违背了我们的“唯一实例”的初衷,因此,我们采取了同步的机制(

    synchronized 

    ),代码如下:

    public class Singleton {
        private static Singleton single = null;
        
        private Singleton() {
            System.out.println("create a singleton class.");
        }
        
        public synchronized static Singleton getInstance() {
            if(null == single) {
                single = new Singleton();
            }
            return single;
        }
        
        public void dosth() {
            System.out.println("do somethings.");
        }
    
    }
    
    public static void main(String[] args) {
            // TODO Auto-generated method stub
            Singleton single = Singleton.getInstance();
            single.dosth();
        }

      但是这样带来了一个新的问题:性能问题。每次访问getInstance都需要进行同步。事实上,我们只需在构造第一个也是唯一一个Singleton类实例的时候进行同步

      我们采用一个Double Check的方式修正上面的代码。

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

      Double Check方式改进:

    • 虽然是多线程环境,但如果没有外层if,客户程序每次执行时都要先synchronized为Singleton类型,但是在绝大多数情况下,每次锁定synchronized类型效率太低,这个锁定很可能就成了整个应用的瓶颈。
    • synchronized加内层的if 组成了一个相对线程安全的实例构造环境。

      虽然看起来Double Check方式很完美,但事实上这个方案还是存在问题:多线程环境下不能确保singleton == null操作的原子性。

      修改后的Double Check方式代码:

    public class Singleton {
    
        private static volatile Singleton singleton = null;
        private Singleton()
        {
            
        }
        
        public static Singleton getInstance() {
            if(singleton == null) {
                synchronized(Singleton.class) {
                    if(singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
  • 相关阅读:
    SSAS aggregation 的作用及其使用
    liblinear使用总结
    python绝对路径相对路径函数
    libsvm使用总结
    一次scrapy成功停止的信息
    简单总结scrapy使用方法
    python编码格式
    一次scrapy失败的提示信息:由于连接方在一段时间后没有正确答复或连接的主机没有反 应,连接尝试失败
    17.1 MySQL主从介绍 17.2 准备工作 17.3 配置主 17.4 配置从 17.5 测试主从同步
    16.1 Tomcat介绍 16.2 安装jdk 16.3 安装Tomcat
  • 原文地址:https://www.cnblogs.com/wiessharling/p/3423026.html
Copyright © 2011-2022 走看看