Head First设计模式(阅读笔记)-05.单例模式
创始人
2024-02-19 03:45:54
0

巧克力工厂

巧克力工厂需要将牛奶和巧克力混合,因此需要一个巧克力锅炉,具体代码如下:


public class ChocolateBoiler{private boolean empty;  // 判断是否为空private boolean boiled;  // 判断是否煮沸public ChocolateBoiler(){  // 刚开始时锅炉是空的empty = true;  boiled = false;}public void fill(){// 锅炉为空时if(isEmpty()){empty = false;boiled = false;// 开始填充牛奶和巧克力}}public void drain(){if(!isEmpty() && isBoiled()){  // 如果锅炉满了而且已煮过// 排除煮沸的巧克力和牛奶empty = true;  // 锅炉重新变为空}}public void boil(){if(!isEmpty() && !isBoiled()){  // 如果锅炉满了而且未煮过// 将混合物煮沸boiled = true;  // 已经煮沸了}}public boolean isEmpty(){return empty;}public boolean isBoiled(){return boiled;}
}

单例模式

确保一个类只有一个实例,并且提供一个全局访问点


经典单例实现

因为只允许一个巧克力锅炉存在,所以自然就想到使用单例模式

这种方式十分简单,但是存在线程不安全的问题(图中出现obj1obj2)


public class ChocolateBoiler{private boolean empty;private boolean boiled;private static ChocolateBoiler uniqueInstance;  // ① 静态变量记录ChocolateBoiler类的唯一实例public static ChocolateBoiler getInstance(){  // ② 提供一个公共方法让外部可以获取到该唯一实例if(uniqueInstance == null){uniqueInstance = new ChocolateBoiler();}return uniqueInstance;}private ChocolateBoiler(){  // ③ 将构造方法改为私有,只有ChocolateBoiler类内部才能调用empty = true;  boiled = false;}// 其他代码一致
}

在这里插入图片描述

处理多线程

既然存在多线程问题,不如将getInstance方法改为同步方法

这样虽然可以解决线程安全问题,但是性能实在过于低下


public class ChocolateBoiler{// 加上synchronized关键字public static synchronized ChocolateBoiler getInstance(){  if(uniqueInstance == null){uniqueInstance = new ChocolateBoiler();}return uniqueInstance;}// 其他代码一致
}

不采用延迟实例化

前两种方式都采用了延迟实例化,如果程序总是创建并使用该单例对象,或者创建和运行该单例对象时负担不重,可以采用静态初始化器创建单例对象

之所以能使用该方法是因为JVM可以保证任何线程访问uniqueInstance静态变量前一定会创建该单例对象


public class ChocolateBoiler{// 在静态初始化器创建单例对象private static ChocolateBoiler uniqueInstance = new ChocolateBoiler(); public static ChocolateBoiler getInstance(){  return uniqueInstance;}// 其他代码一致
}

使用双重检查锁

先检查是否创建了实例,如果未创建再进行同步,该方法的是否必须保证再Java5以上的版本


public class ChocolateBoiler{// 在静态初始化器创建单例对象private volatile static ChocolateBoiler uniqueInstance;  // 这里需要使用volatile关键字public static ChocolateBoiler getInstance(){  if(uniqueInstance = null){synchronized(ChocolateBoiler.class){if(uniqueInstance = null){uniqueInstance = new ChocolateBoiler();}}}return uniqueInstance;}// 其他代码一致
}

参考

Head First 设计模式-单例模式

设计模式-单例模式

java 单例模式中双重检查锁定 volatile 的作用?

相关内容

热门资讯

做实公益诉讼 守护峡江文脉(法... 本报记者 姜 峰 图①:重庆市忠县人民检察院检察官现场查看石宝寨寨门。 张海波摄 图②:重庆市巫溪...
法院:驳回诉讼请求 员工举报上司职场霸凌反被起诉侵犯名誉权 法院:驳回诉讼请求 员工向公司领导、同事发送邮件举报上司职...
大唐电信科技股份有限公司关于公... 本公司董事会及全体董事保证本公告内容不存在任何虚假记载、误导性陈述或者重大遗漏,并对其内容的真实性、...
深圳广田集团股份有限公司 关于... 本公司及董事会全体成员保证信息披露的内容真实、准确、完整,没有虚假记载、误导性陈述或重大遗漏。 深圳...
广东华特气体股份有限公司 关于... 本公司董事会及全体董事保证本公告内容不存在任何虚假记载、误导性陈述或者重大遗漏,并对其内容的真实性、...
英国推出新措施打击侵害妇女和女... 中新社伦敦12月17日电 (欧阳开宇 刘施岑)英国内政部17日宣布推出一项打击侵害妇女和女童暴力犯罪...
海南封关绘就开放新图景 上市公... 图①为三亚大东海旅游区。 图②为海口复兴城互联网信息产业园。 图③为博鳌乐城国际医疗旅游先行区。...
法国内政部网络系统遭入侵:数据... 大象新闻2025-12-17 23:06:30 法国内政部长洛朗·努内兹17日接受法国新闻广播电台采...
北京市永定河保护条例 北京市人民代表大会常务委员会公告 〔十六届〕第47号 《北京市永定河保护条例》已由北京市第十六届人民...
专访海南社科院王艳婷:从“打开... 12月18日,海南即将启动全岛封关运作,成为中国对外开放历程中的一个里程碑事件。 在此背景下,海南省...