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

Java设计模式之单例模式

  一、概述
  所谓单例,指的就是单实例,有且仅有一个类实例,这个单例不应该由人来控制,而应该由代码来限制,强制单例。
  单例有其独有的使用场景,一般是对于那些业务逻辑上限定不能多例只能单例的情况,例如:类似于计数器之类的存在,一般都需要使用一个实例来进行记录,若多例计数则会不准确。
  其实单例就是那些很明显的使用场合,没有之前学习的那些模式所使用的复杂场景,只要你需要使用单例,那你就使用单例,简单易理解。
  所以我认为有关单例模式的重点不在于场景,而在于如何使用。二、单例实现2.1 懒汉式
  何为懒?顾名思义,就是不做事,这里也是同义,懒汉式就是不在系统加载时就创建类的单例,而是在第一次使用实例的时候再创建。
  详见下方代码示例:public class LHanDanli {     // 定义一个私有类变量来存放单例,私有的目的是指外部无法     // 直接获取这个变量,而要使用提供的公共方法来获取     private static LHanDanli dl = null;     // 定义私有构造器,表示只在类内部使用,     // 亦指单例的实例只能在单例类内部创建     private LHanDanli(){}     // 定义一个公共的公开的方法来返回该类的实例,     // 由于是懒汉式,需要在第一次使用时生成实例,     // 所以为了线程安全,使用synchronized关键字来确保只会生成单例     public static synchronized LHanDanli getInstance(){         if(dl == null){             dl = new LHanDanli();         }         return dl;     } }2.2 饿汉式
  又何为饿?饿者,饥不择食;但凡有食,必急食之。此处同义:在加载类的时候就会创建类的单例,并保存在类中。
  详见下方代码示例:public class EHanDanli {     // 此处定义类变量实例并直接实例化,     // 在类加载的时候就完成了实例化并保存在类中     private static EHanDanli dl = new EHanDanli();     // 定义无参构造器,用于单例实例     private EHanDanli(){}     // 定义公开方法,返回已创建的单例     public static EHanDanli getInstance(){         return dl;     } }2.3 双重加锁机制
  何为双重加锁机制?
  在懒汉式实现单例模式的代码中,有使用synchronized关键字来同步获取实例,保证单例的唯一性,但是上面的代码在每一次执行时都要进行同步和判断,无疑会拖慢速度,使用双重加锁机制正好可以解决这个问题:public class SLHanDanli {     private static volatile SLHanDanli dl = null;     private SLHanDanli(){}     public static SLHanDanli getInstance(){         if(dl == null){             synchronized (SLHanDanli.class) {                 if(dl == null){                     dl = new SLHanDanli();                 }             }         }         return dl;     } }
  看了上面的代码,有没有感觉很无语,双重加锁难道不是需要两个synchronized进行加锁的吗?
  ...
  其实不然,这里的双重指的的双重判断,而加锁单指那个synchronized,为什么要进行双重判断,其实很简单,第一重判断,如果单例已经存在,那么就不再需要进行同步操作,而是直接返回这个实例,如果没有创建,才会进入同步块,同步块的目的与之前相同,目的是为了防止有两个调用同时进行时,导致生成多个实例,有了同步块,每次只能有一个线程调用能访问同步块内容,当第一个抢到锁的调用获取了实例之后,这个实例就会被创建,之后的所有调用都不会进入同步块,直接在第一重判断就返回了单例。
  关于锁内部的第二重空判断的作用,当多个线程一起到达锁位置时,进行锁竞争,其中一个线程获取锁,如果是第一次进入则dl为null,会进行单例对象的创建,完成后释放锁,其他线程获取锁后就会被空判断拦截,直接返回已创建的单例对象。
  不论如何,使用了双重加锁机制后,程序的执行速度有了显著提升,不必每次都同步加锁。
  其实我最在意的是volatile的使用,volatile关键字的含义是:被其所修饰的变量的值不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存来实现,从而确保多个线程能正确的处理该变量。该关键字可能会屏蔽掉虚拟机中的一些代码优化,所以其运行效率可能不是很高,所以,一般情况下,并不建议使用双重加锁机制,酌情使用才是正理!
  更进一步说,其实使用volatile的目的是为了防止暴露一个未初始化的不完整单例实例,导致系统崩溃。因为创建单例实例其实需要经过以下几步:首先分配内存空间、然后将内存空间的首地址指向引用(指针),最后调用构造器创建实例,由于在第二步的时候这个引用(指针)就会变的非null,那么在第三步未执行,真正的单例实例还未创建完成的时候,一个线程过来在第一个校验中为false,将会直接将不完整的实例返回,从而造成系统崩溃。2.4 类级内部类方式
  饿汉式会占用较多的空间,因为其在类加载时就会完成实例化,而懒汉式又存在执行速率慢的情况,双重加锁机制呢?又有执行效率差的毛病,有没有一种完美的方式可以规避这些毛病呢?
  貌似有的,就是使用类级内部类结合多线程默认同步锁,同时实现延迟加载和线程安全。public class ClassInnerClassDanli {     public static class DanliHolder{         private static ClassInnerClassDanli dl = new ClassInnerClassDanli();     }     private ClassInnerClassDanli(){}     public static ClassInnerClassDanli getInstance(){         return DanliHolder.dl;     } }
  如上代码,所谓类级内部类,就是静态内部类,这种内部类与其外部类之间并没有从属关系,加载外部类的时候,并不会同时加载其静态内部类,只有在发生调用的时候才会进行加载,加载的时候就会创建单例实例并返回,有效实现了懒加载(延迟加载),至于同步问题,我们采用和饿汉式同样的静态初始化器的方式,借助JVM来实现线程安全。
  其实使用静态初始化器的方式会在类加载时创建类的实例,但是我们将实例的创建显式放置在静态内部类中,它会导致在外部类加载时不进行实例创建,这样就能实现我们的双重目的:延迟加载和线程安全。四、使用
  在Spring中创建的Bean实例默认都是单例模式存在的。

小米12系列最实惠机型将至!曝小米12Lite5G即将推出据xiaomiui。net报道,小米已经在测试小米12Lite新机,预计很快会在亚洲和欧洲推出。小米12Lite将是小米12智能手机阵容的最新成员,也是该系列最实惠的设备。该媒体表RedmiK50Pro真机上手!连夜潜入小米之家,2999花得到底值不值?RedmiK50系列已经正式发布了,仅发布一天就狂卖根据各大KOL和网友们的观点,大家普遍都认为K50系列配置不错,无愧性价比旗舰之名!从先前的预热能看出,Redmi官方对K50系特斯拉ModelY低配版也涨价了特斯拉中国官网显示,ModelY后轮驱动版最新售价31。69万元,涨了15060元,是特斯拉7天内第3次涨价该车型自去年底以来首次涨价。至此,特斯拉最畅销的Model3ModelY3款高续航电动车,全国能上牌,续航200公里以上,不用经常的充电您在阅读前请点击上面的关注二字,后续会为您提供更多有价值的相关内容,感谢您的支持。高续航电动车虽然相对价格比较高,但它因为不用经常充电,能跑远距离,还是具有一定的优势,因此,现在越几乎零差评的3款手机,价格覆盖中端高端,性价比非常高大浪淘沙以后,目前留下来的手机品牌,可以说是各有所长,自己都有自己的两把刷子,国产手机的产品力也是直线提升,不过在高端智能手机领域,苹果还是一枝独秀,尤其是iPhone13系列推出友商坚持性价比,骁龙888Plus144Hz屏,512G仅2499元前些日子RedmiK50系列发布,带走了不少用户的关注度,标准版和Pro版的性价比都很出色,尤其是全球首发天玑8100的RedmiK50,起售价仅为2399元,基本是不赚钱和用户交安卓阵型迎来狂欢,小米发布50W磁吸无线快充技术三十年河东三十年河西,无线充电曾是安卓旗舰标配的功能,苹果自iPhone8后全系手机标配无线充,并在iPhone12开始开辟新玩法,全系升级至MagSafe磁吸无线充,一改无线充电红米K50K50ProK40SK50电竞版,这三四款手机哪款更好?红米这次那K50电竞版打头阵,虽然配置很香,但却没有8256的版本,内存配置可以说非常不合理的。加之游戏方面还出现了强制降分辨率的情况,这个大米测评那边有专门测试过。加之高达329东数西算工程系列解读之四自去年5月底发布全国一体化大数据中心协同创新体系算力枢纽实施方案以来,东数西算工程受到社会各界广泛关注。当前,随着京津冀甘肃等8地算力网络国家枢纽节点获得正式批复,2022年将作为vivo影像配置,继续升级,确实很值得期待说起vivo,最近几年他的知名度提升了非常多,不仅仅是因为性能非常高,同时拍照效果也深受大家的喜爱,现在的产品和以往相比做了非常大的提升,对于现消费者来说,更加满足他们的需求,并且一机双芯新赛道,各大厂商陆续进场,卷王宝座花落谁家?如果说十年前智能手机在拼性能,五年前智能手机在拼屏幕,那么到现在2022年,智能手机就可以说已经进入到了拼芯片的阶段,或者准确来说,就是拼产品的差异化,谁能够通过芯片与其它产品打出
52岁的我,今天开始学习人工智能今天决定开始学习人工智能33年前,特别喜欢人工智能,当时买了复旦大学版的三本教材概率论数理统计和随机过程,买了徐光佑的人工智能,经常听吴朝晖谈人工智能,特别是专家系统和知识库。可是折叠屏才出现几年,华为又革新了它的新形态刚拿到华为P50Pocket的时候,我的第一反应就是很小巧,拿在手上具备美感,放进透明的小包包也十分好看,不占位置。轻薄的它还可以放进口袋里,确实很像它的英文名pocket,翻译过2022年三款新机官宣1月45日,正式发布,新一波旗舰机开始2021年各大手机品牌基本圆满结束,而2022年的新机也开始陆续预热公布或官宣。从已公布的新机中基本都是旗舰机,毕竟高通的骁龙8Gen1联发科的天玑9000芯片都是搭载在旗舰机上,教程9国产编程语言Cbrother数组ArrayCBrother数组是任何对象的有序整数索引集合,数组的索引从0开始,CBrother数组不需要指定大小,当向数组添加元素时,CBrother数组会自动增长。函数描述参数Md5Md5Crypt加盐加密密码操作Md5优点快速计算m,具有单向性oneway,不可由散列值推出原消息,但是如果密码过于简单就会有一定概率被暴力破解。密码存储常用方式1双重MD52MD5加盐3双重MD5加盐我一般使盘点JavaScript中那些进阶操作知识(上篇)前言相信做网站对JavaScript再熟悉不过了,它是一门脚本语言,不同于Python的是,它是一门浏览器脚本语言,而Python则是服务器脚本语言,我们不光要会Python,还要小米12和小米12Pro相比较,该如何选择?如果非要在这两款手机中选择一款手机进行购买,小芳我个人是更加倾向于小米12Pro这款手机会更多一些的。不过大家在购买手机的过程当中,因为关注的购机因素是会存在差异的。那么做出的最终南卡RunnerPro3骨传导运动耳机升级不止一点点自从3。5mm耳机接口取消后,蓝牙耳机已经成为手机的标配,且耳机功能定位也越来越细化精准。现在很多年轻人开始注重自身健康问题,尤其是对于喜欢户外跑游泳等运动的人来说,骨传导耳机估计首发丨非洲电商新势力卜鸣集团完成华盛人和资本领投天使轮融资创业邦获悉,2021年12月5日,卜鸣集团旗下Topspin电商平台于近期完成天使轮融资,由华盛人和资本领投,投后估值1亿元人民币。本轮融资将主要用于团队扩充市场推广完善仓储物流供等了8年,微信淘宝迎来和解先有互联,才有互联网微信与淘宝的和解,等了8年,虽迟但到。难怪有网友说这是微信和淘宝的一小步,也是中国互联网的一大步。都说有人的地方,就有江湖,更有利益纠葛。早在十几年前,移动互联时代方兴未艾之时,大Rust编程语言里的replace,take是真的很有用在一些crate里都有replace和take方法。这里略做整理,以便有个清晰的了解。它们在一些场景,非常有意义,有无法取代的作用。memreplace可以用来替换并返回被替换掉的