zoukankan      html  css  js  c++  java
  • 单例模式(含线程锁关键字)

    单例就是只有一个例子,只有一个对象,不允许别人再创建对象。

    饿汉式(初始化即创建对象)

    class Single{
    
      private static 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)      //语句①
    
          s = new Single();//语句②
    
        return s;
    
      }
    
    }

    懒汉式看似省空间,却有可能在多线程时出问题。

    举个只有两个线程的例子:线程A被单核CPU执行到①,单核CPU切入线程B去执行①,仍然会通过判断,此时A,B都会执行语句②。

    改进后的安全懒汉式(低效,在方法上增加了线程锁):

    class Single{
    
      private static Single s = null;
    
      private Single(){}
    
      public synchronized static Single getInstance(){
    
        if(s == null)      //语句①
    
          s = new Single();//语句②
    
        return s;
    
      }
    
    }

    tips:

    线程锁就是synchronized后边的参数,汉语版的API中作者称之为对象监视器。线程锁有两个状态,一个锁住一个打开,打开的时候线程就能进去,关闭的时候,线程就会在门前等待,直到锁打开才会进去。 

    synchronized相当于一个标示符表示它所跟随的大括号内的内容是同步代码块,执行这部分代码块就要判断线程锁的状态。

    再次改进后最终的懒汉式(在方法内部增加线程锁)

    class Single{
    
      private static Single s = null;
    
      private Single(){}
    
      public static Single getInstance(){
    
        if(s == null){      //语句①
    
          synchronized (Single.class){ //语句② 这样就会最多判断两次线程锁
    
            if(s == null) //语句③
    
              s = new Single();//语句④
    
          }
    
        }
    
        return s;
    
      }
    
    }

    解析一下:线程A执行语句①通过,执行语句②通过,此时CPU切入线程B执行到语句①通过,执行到语句②未通过,

    然后CPU切入线程A继续执行,通过语句③和④并解除线程锁,CPU再次切入线程B,此时会通过语句②,执行语句③,

    如果没有语句③又悲剧了。。。

    总结,既然有这么一个单例类,肯定你是要用它的,你要用它一定会开辟内存存放它的对象,

    懒汉实在是浪费时间又没什么实际意义,所以建议选择饿汉式的单例模式。

  • 相关阅读:
    检查 Linux 服务器性能
    openssl、x509、crt、cer、key、csr、ssl、tls 这些都是什么鬼?
    Jenkins+ Xcode+ 蒲公英 实现IOS自动化打包和分发
    如何在 Linux 上录制你的终端操作
    Swift 开源 Linux Ubuntu Install
    SCP 命令
    ubuntu openfire Server install
    git 和 svn 的比较
    implicitly declaring function 'malloc' with type void *(unsigned long ) 错误 解决
    python 使用缓存加快运算
  • 原文地址:https://www.cnblogs.com/flying607/p/3418758.html
Copyright © 2011-2022 走看看