zoukankan      html  css  js  c++  java
  • 设计模式-单件模式

    工程中,某些对象我们只需要一个,比如线程池,缓存,对话框等的对象,我们通常的做法是可以定一个全局静态变量,然后通过程序初始化的时候就实例化他们,然后直接调用这个全局变量,但是这样有个问题,如果我的这个对象消耗的资源很多,而有的时候,我的程序在运行过程中又没用到这个对象,岂不是浪费了很多资源。通常的做法就是定义全局静态变量的时候,不初始化他,而是在调用过程中实例化,这样的话,对于全局变量的实例化,我们就要判断这个变量是否已经实例化了,如果实例化了的吧,我们就不对它进行实例化,所以代码如下:

    public class A
    {
        private A(){}
        public static A cla;
        public static A getInstance()
        {
            if (cla == null){
                cla=new A();
            }
            return cla;
        }
    }

    这里的A的构造器是私有的,这样子可以有效的保证A这个类不会再外部被实例化,从而保证他的唯一性,我们通过getInstance来获取A的全局唯一变量cla,这样就有效的解决了上面这个问题,但是问题又来了,多线程访问getInstance()的时候?cla完全可能出现实例化一次之后又被实例化,怎么办?

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

    我们就为A获取实力的方法getInstance增加一个同步锁来保证方法只能被唯一访问,可是,同步锁势必会降低运行效率,而且我们发现,事实上,也就是第一次实例化的时候会出现问题需要同步锁,以后再需要获取这个对象的时候完全不需要,如果我们频繁的获取对象的话,效率的影响就会相当大。回到最开始的做法?设置全局变量,程序运行的时候就实例化对象?

    public class A
    {
        private A(){}
        public static A cla = new A();
        public static synchronized A getInstance()
        {
            return cla;
         }
    }

    这个确实是种方法,但始终不是最好的方法,我们想到,之前所说的,只有在实例化的时候才需要同步锁,那么我们就想到采用双重检查加锁的方法,只在实例化的时候加锁:

    public class A
    {
        private A(){}
        public volatile static A cla;
        public static A getInstance()
        {
             if (cla == null){
                synchronized(A.class){
                    if (cla==null){
                        cla=new A();
                    }
                }
              }
            return cla;
        }
    }

    其中volatile的关键字是确保多线程在cla变量初始化的时候,正确的处理cla变量。(volatile用在多线程,同步变量。 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B。只在某些动作时才进行A和B的同步。因此存在A和B不一致的情况。volatile就是用来避免这种情况的。volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中的(也就是上面说的A))

  • 相关阅读:
    UPNP报文示例
    ceph旧版客户端挂载新版ceph报错
    VUE——配置本地运行指定不同环境
    springBoot——Web开发简介【七】
    C++ 浮点数的存储与精度
    端口复用与惊群效应
    MySQL5.5读写分离之mysql-proxy
    Mysql读写分离--mysql-proxy
    mysql主从之keepalive+MySQL高可用
    如何在CentOS 7上安装Htop
  • 原文地址:https://www.cnblogs.com/xtestw/p/3951431.html
Copyright © 2011-2022 走看看