zoukankan      html  css  js  c++  java
  • 单例

    public class SingleTonTest {
         //单例全解
         
         //第一种,懒汉模式(非线程安全的写法)
         
         private SingleTonTest(){};                      //私有化构造函数,因为不能随便让其new对象,故采用private私有化构造函数。
         
         private static SingleTonTest instance = null;   //创建单例对象
         
         public static SingleTonTest getInstance(){      //获取单例对象的方法
               
               if (instance == null){                    //如果单例初始值是null,说明对象还没有被创建,
                                                         //(当instance刚被初始化,此时若有两个线程同时访问,instance还是空的,两个线程会同时调用getInstance方法,
                                                         //此时,两个线程都会判断通过,开始执行new,就会创建两个对象。)
                    
                    instance = new SingleTonTest();      //则创建对象
                    
               }                                                          
               return instance;                          //并返回instance对象返回
               
         }
    }
     
    public class SingleTonTest {
         // 第二种。(线程安全的)
         private SingleTonTest() {};                               // 私有化构造函数,因为不能随便让其new对象,故采用private私有化构造函数。
     
         private static SingleTonTest instance = null;             // 创建单例对象
     
         public static SingleTonTest getInstance() {               // 获取单例对象的方法
     
               if (instance == null) {                             // 双重检测机制
                    synchronized (SingleTonTest.class) {           // 同步锁。为了防止new SingleTonTest 被多次执行,synchronized,每次只允许一个线程访问对象
                         if (instance == null) {                   // 进入Synchronized 临界区以后,还要再做一次判空。因为当两个线程同时访问的时候,线程A构建完对象,
                                                                   // 线程B也已经通过了最初的判空验证,不做第二次判空的话,线程B还是会再次构建instance对象。
                               instance = new SingleTonTest();     // 则创建对象
                         }
                    }
               }
               return instance;                                    // 并返回instance对象返回
     
         }
    //此时也不是绝对的线程安全
    }
     
         //指令重排是:比如java中简单的一句 instance = new Singleton,会被编译器编译成如下JVM指令:
     
         memory =allocate();                    //1:分配对象的内存空间
         ctorInstance(memory);                  //2:初始化对象
         instance =memory;                      //3:设置instance指向刚分配的内存地址
     
                                                //但是这些指令顺序并非一成不变,有可能会经过JVM和CPU的优化,指令重排成下面的顺序:
     
         memory =allocate();                    //1:分配对象的内存空间
         instance =memory;                      //3:设置instance指向刚分配的内存地址
         ctorInstance(memory);                  //2:初始化对象
     
                                                //当线程A执行完1,3,时,instance对象还未完成初始化,但已经不再指向null。此时如果线程B抢占到CPU资源,
                                                //执行  if(instance == null)的结果会是false,从而返回一个没有初始化完成的instance对象。
     
     
    //如何避免这一情况,我们需要在instance对象前面增加一个修饰符volatile。
     
    public class SingleTonTest {
                //第三种
         private SingleTonTest() {} // 私有构造函数
     
         private volatile static SingleTonTest instance = null; // 单例对象
     
         public static SingleTonTest getInstance() {            // 静态工厂方法
               if (instance == null) {
                    synchronized (SingleTonTest.class) {
                         if (instance == null) {
                               instance = new SingleTonTest();
                         }
                    }
               }
     
               return instance;
     
         }
    }
     
    //经过volatile的修饰,当线程A执行instance = new Singleton的时候,JVM执行顺序是什么样?始终保证是下面的顺序:
     
    memory =allocate();    //1:分配对象的内存空间
    ctorInstance(memory);  //2:初始化对象
    instance =memory;     //3:设置instance指向刚分配的内存地址
     
    //如此在线程B看来,instance对象的引用要么指向null,要么指向一个初始化完毕的Instance,而不会出现某个中间态,保证了安全。
     
     
     
     
     
  • 相关阅读:
    sqlserver创建链接服务器连接sqlserver脚本
    两步快速获取小程序源码
    SQL判断是否存在该数据 有则更新,没有则插入
    利用c#+jquery+echarts生成统计报表(附源代码)
    每晚定时重启IIS和数据库服务可节省服务器资源
    SQL中的循环、for循环、游标
    sql的行转列(PIVOT)与列转行(UNPIVOT)
    SQLServer 简单数据拆分
    IIS安装与MVC程序部署
    (六)HTTP和HTTPS(转)
  • 原文地址:https://www.cnblogs.com/huike/p/8001136.html
Copyright © 2011-2022 走看看