范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

单例模式(二)

  昨天介绍了最简单的单例模式,需要回看的可以从这里直接进入:
  单例模式(一)
  今天我们继续来深入探讨单例模式,还是以宇宙、地球和人的关系为例,
  昨天我们为了创建地球这样一个全局的、唯一的、共享的对象,我们的代码是这样设计的:
  public class Earth {      private static Earth earth = new Earth();      private Earth(){         System.out.println("构造函数");     }          public static Earth getInstance(){         return earth;     } }
  我们仔细分析代码,可以看到private  static  Earth earth = new  Earth()这行代码是声明了一个静态对象,这个静态对象是在类初始化的时候就会生成,当外部其他类来调用地球这个对象的时候,就不需要做任何初始化了,看起来是一件未雨绸缪的事情。
  这时候我们加一个新的需求:当有外部类调用地球这个对象的时候,地球再生成对象;这个需求我们可以这样假设,假如人类一开始是直接生存在宇宙中的,不寄生于任何星球,有一天人类意识到宇宙实在是太大,大家通信实在不方便、成本高,于是向宇宙这个系统发出一个需求指令:能不能创建一个新的星球,让人类移居到这个新的星球上,大家聚在一块,这样沟通成本低、通信方便。 这时候,我们就得给这个需求设定一个新的逻辑:假设地球一开始是不存在,当人类需要的时候,及时给创建出来,如何设计呢?
  还是在原有的代码上做改良,地球这个类唯一暴露给外部类访问的一个方法就是getInstance():
  public static Earth getInstance(){         return earth; }
  而之前的代码,我们知道,其实earth这个对象是早已经生成好的,这时候我们需要对这里的逻辑做改动:
  public class Earth {      // private static Earth earth = new Earth();      private static Earth earth;            private Earth(){         System.out.println("构造函数");      }            /** public static Earth getInstance(){         return earth;      }*/       public static Earth getInstance(){         return new Earth();      }       }
  通过注释掉的代码,我们可以发现,我们把对象创建的时机挪到了外部类调用的时候,这样就满足了调用时再生成地球对象的原则,但是问题来了,这样的话,如果有5个人来调用getInstance()方法,就会得到5个不同的对象,我们仍然可以用上一节介绍的测试方式:多线程模拟5个人类请求的方式来测试下:
  你会发现,测试的结果是打印出了5个不同的对象地址,这就一下子破坏了单例对象唯一性的原则,我们接着来推敲代码,有人可能会发现,每次我们都是return  new  Earth(); 如果在这句话上面加一个IF判断,是不是就能解决这个问题了呢:
  if (earth == null){    earth = new Earth(); } return earth;
  基本上能够想到这里,也就是走在正确的路上了,我们先判断下地球这个对象是否已经被初始化了,如果没有初始化(== null ) ,再去创建,如果已经初始化过了,就直接返回初始化过的对象,我们再来测试下:
  你会惊奇地发现5个人类去调用,其中有4个人类调用的结果是获取同一个对象,而其中1个人获取到一个不同的对象,如果再多运行几遍,你可能会发现这样的结果:
  这回是3个人调用的结果是获取同一个对象,而另外2个人分别获取了不同的对象,这是为什么?其实当你运行测试代码多次后,通过采样,会发现,有时候能够获得预期的结果,5个人获取同一个对象,而有时获得是不同的对象,接下来我们解决这个概率问题,让每一次获得的对象都是同一个对象,首先要找出问题到底出现在哪里? 归根结底的问题还是在这里:
  if(earth == null){        earth = new Earth();   }   return earth;
  我们模拟用户调用行为用的是多线程并发的测试方式,而上面这段代码是一段任何线程都可以公共访问的代码段,而多线程并发访问这段代码时的顺序有快慢,我们把这段代码分成3个语句块:
  语句1 : if(earth == null) 语句2 : earth = new Earth(); 语句3 : return earth;
  假设有A、B两个线程,因为线程的执行和速度和操作系统本身的调度有关,所以可能会有如下几种情况发生:
  当A还没访问语句1的时候,B已经去访问语句2了,所以这时候,A再去访问语句1,就发现对象已经初始化过了,那么这时候A、B会得到相同的对象当A访问语句1的时候,B已经访问语句2了,这时候A再去访问语句2,会生成一个新的对象,结果A、B会得到不同的对象
  所以这就导致了我们上面的测试结果,那么可能你会疑问,就不能让多个线程去顺序排队去调用这个公用方法吗?答案是可以的,的确,如果多个线程顺序排队去访问这段公用方法,就能让所有线程得到同一个对象,因为只要第一个线程访问过语句2后,其他线程再去访问语句1的时候,就会得到earth != null 的结果,然后就执行语句3,最终使所有线程得到的是同一个对象。
  那么如果现在要应对的是线程无法排队顺序访问的情况呢,或者说你都不知道调用方是如何调用的,但是我们必须确保的是不管调用方怎么调用,我们都能返回一个唯一的对象,我们继续来对代码推敲:
  public static Earth getInstance(){        synchronized (Earth.class){           if(earth == null){              earth = new Earth();           }        }        return earth;   }
  不难发现,我们在外层加了一层锁机制:sychronized, 这把锁就能保证不管有多少个线程,在锁里面的代码同一时刻只能被一个线程访问,再来看下测试结果:
  结果会发现,不管你运行多少次,每一次都能返回同一个对象,到这里就解决了多线程访问的唯一性问题,并且也解决了上面提出的需求:当需要地球这个对象的时候再去生成。
  今天主要介绍了单例模式的另外一种写法,下一篇会介绍单例模式的优化以及常用的几种单例模式写法上的区别。

为中国星铸就通天坦途!今年我国航天发射仍保持超高密度来源央视新闻客户端2月27日7时44分11时06分,我国使用长征四号丙火箭和长征八号火箭,先后成功发射LSAR01组B星,以及泰景三号01星等22颗商业卫星。西安卫星测控中心作为测创纪录!一箭22星,长征八号成功发射央视网消息2月27日上午,长征八号遥二运载火箭在文昌航天发射场点火升空,成功将22颗卫星送入预定轨道,这次发射创造了我国一箭多星发射的新纪录。长征八号火箭是我国自主研制的中型运载火祝贺!我国成功发射陆地探测一号01组B星中国青年报客户端北京2月27日电(何家玲中青报中青网记者邱晨辉)2月27日7时44分,我国在酒泉卫星发射中心采用长征四号丙遥三十运载火箭,成功发射陆地探测一号01组B星(L波段差分七个国际基本单位即将更简化本老拳时空是一对的。无量子定义就是这样,成对同时出现。海森堡不确定原理的最终根源就在这。宇宙,宇和宙,无法同时精确。原因是无量子的运动速度。无量子运动在宇宙里是最高的,也是最基础的SpaceX星链遭太阳风暴袭击,40颗卫星被摧毁,损失至少1。28亿元极目新闻记者张扬实习生方梓奕受太阳风暴影响,美国SpaceX的卫星群星链正在脱离轨道,坠入大气层烧毁。据美联社报道,该公司于2月7日晚发布了最新声明,称在上周发射的49颗卫星中,至常年有人照料的中国空间站今年建成来源光明日报本报北京2月9日电记者张蕾从空间瞭望智库9日在北京举行的中国航天科技活动蓝皮书(2021年)新闻发布会上获悉,我国载人航天空间站工程今年计划实施6次发射任务,包括天舟四国际空间站退役,法国宇航员开始学中文,中国太空计划崛起近日美国NASA航空航天局对外宣布了国际空间站的最终退役时间,即2031年1月,届时国际空间站将由3艘俄罗斯进步号飞船将空间站整个拉出所在轨道,并坠入南太平洋的无人居住区域。由此看灭绝恐龙的小行星撞击发生在春季增加了其他物种的灭绝率小行星撞击地球对恐龙来说是灾难性的,一项新研究表明撞击发生的季节可能大大增加了其他物种的灭绝率。有证据表明,6600万年前那场毁灭性的撞击发生在北半球的春天,它消灭了地球上四分之三研究显示恐龙时代或于远古某春季开启末世新华社北京2月25日电参考消息25日登载美国科学新闻双周刊网站报道恐龙时代可能是在春季结束的。报道摘要如下大约6600万年前,一颗直径达10公里的小行星撞上地球。不久后,所有非鸟类研究人员在北达科他州发现恐龙灭绝事件的新细节6600万年前,灾难性的小行星撞击事件消灭了地球上的大部分生命体,包括所有的菊石类翼龙非鸟恐龙和大部分海洋爬行动物。这一大规模灭绝事件的一个名副其实的杀戮场以化石的形式保存在现代北期待!常年有人照料的中国空间站今年建成从空间瞭望智库9日在北京举行的中国航天科技活动蓝皮书(2021年)新闻发布会上获悉,我国载人航天空间站工程今年计划实施6次发射任务,包括天舟四号和天舟五号两次货运飞船神舟十四号和神
Kavango在Ditau稀土项目中确定了七个目标目标相对较浅,这应该可以直接确定该项目的潜力。Ditau现场KavangoResourcesPLC(LONKAV)表示,博茨瓦纳Ditau稀土项目的地质调查确定了七个目标,其中三个秘鲁采矿业发展面临不确定性据BNAmericas网站报道,在6月6日秘鲁总统大选中领先的佩德罗卡斯蒂略(PedroCastillo)将组阁新政府,但前能矿部两名高官却表示,该国530亿美元的矿业投资项目面临CFACT让我们停止谈论化石燃料,谈谈技术地图是什么?大多数人都很熟悉六度分离的概念这个星球上的每个人只被六种关系所分隔。我想给你们介绍一下70度连接的概念。在当今世界,我们大多数时候都希望有一个舒适的70(华氏)度左右的温度。人们谈Lynas稀土季度总产量下降,但收入大增稀土公司Lynas日前发布了2021财年第四季度市场报告,在需求和市场行情推动下,其季度收入和销售收入均创了纪录。根据报告,销售收入为1。859亿澳元,比上一季度增长69同比增长3北方稀土挂牌价格上调,稀土市场仍然行走于上行通道7月9日,中国北方稀土(集团)高科技股份有限公司公布2021年7月轻稀土产品挂牌价格整体偏强,继3个月下调之后出现价格首度上升。同期,稀土现货市场价格表现为整体上行。具体而言,氧化Gobitz铜价下跌据MetalMiner的MariaRosaGobitz报道,伦敦金属交易所(LondonMetalExchange)3个月期铜价6月份下跌了7。5。铜价在5月份触及历史高点后,6月莱纳斯稀土公司获得了1480万澳元的拨款Lynas稀土公司上周四宣布,作为澳大利亚政府现代制造业计划的一部分,该公司获得了一笔1480万澳元(1090万美元)的拨款。这笔资金将使Lynas实现行业首个稀土碳酸盐精炼工艺的美国稀土公司(AmericanRareEarths)即将完成对Laramie的收购Laramie稀土元素项目的收购反映了ARR对其美国控股公司的长期战略,即在该行业建立市场领导地位,并满足中国对国内供应日益增长的需求。Laramie项目包括超过1,108公顷的矿美国构筑稀土产业链和供应链的工作在努力推进今年以来,多项政策指向了美国稀土供应的重建,包括一些具体的法规及其条款以及从煤提炼稀土的一些项目拨款。7月中旬,随着稀土碳酸盐从WhiteMesa运往Neo,外媒表示美欧构筑一条新欧盟计划稀土补贴呼应美国钕铁硼补贴模式援引外媒报道,欧盟草案文件显示,扶持措施包括提供低息贷款,以及对成本较高的稀土提供补贴。欧盟采用的是美国模式,美国最近为国内制造商推出了税收减免政策(补贴)。知情人士表示,计划的主第二季度美国关键矿物进口同比增长7。9英文来源MINING。com编译产业前沿根据标准普尔全球市场情报的分析,美国关键矿产的进口在第二季度同比增长了7。9,但与上季度相比保持相对平稳。该报告显示,2021年上半年,流入