java设计模式之单例模式的5种写法
《2019年阿里云双11活动拼团》:https://www.aliyun.com/1111/2019/group-buying-share
【限时】1年86元,3年229元,用来建站和编程学习【附WordPress建站教程】
饱汉模式(懒汉模式)
1 // 饱汉 2 // UnThreadSafe 3 public class Singleton1 { 4 private static Singleton1 singleton = null; 5 private Singleton1() { 6 } 7 public static Singleton1 getInstance() { 8 if (singleton == null) { 9 singleton = new Singleton1(); 10 } 11 return singleton; 12 } 13 }
优点:懒加载启动快,资源占用小,使用时才实例化,无锁。
缺点:非线程安全。
饱汉模式(懒汉模式)--线程安全
1 public class Singleton { 2 3 /** 4 * 定义一个变量来存储创建好的类实例 5 */ 6 7 private static Singleton uniqueInstance = null; 8 9 /** 10 * 私有化构造方法,好在内部控制创建实例的数目 11 */ 12 13 private Singleton(){ 14 } 15 16 /** 17 * 定义一个方法来为客户端提供类实例 18 * @return 一个Singleton的实例 19 */ 20 21 public static synchronized Singleton getInstance(){ 22 23 //判断存储实例的变量是否有值 24 if(uniqueInstance == null){ 25 //如果没有,就创建一个类实例,并把值赋值给存储类实例的变量 26 uniqueInstance = new Singleton(); 27 } 28 29 //如果有值,那就直接使用 30 return uniqueInstance; 31 } 32 33 /** 34 * 示意方法,单例可以有自己的操作 35 */ 36 37 public void singletonOperation(){ 38 39 //功能处理 40 41 } 42 43 /** 44 * 示意属性,单例可以有自己的属性 45 */ 46 47 private String singletonData; 48 49 /** 50 * 示意方法,让外部通过这些方法来访问属性的值 51 * @return 属性的值 52 */ 53 54 public String getSingletonData(){ 55 56 return singletonData; 57 58 } 59 60 }
优点:同上,但加锁了。
缺点:synchronized 为独占排他锁,并发性能差。即使在创建成功以后,获取实例仍然是串行化操作。
饱汉模式(懒汉模式)--双重加锁检查DCL(Double Check Lock)
1 public class Singleton { 2 3 /** 4 * 对保存实例的变量添加volatile的修饰 5 */ 6 7 private volatile static Singleton instance = null; 8 9 private Singleton(){ 10 11 } 12 13 public static Singleton getInstance(){ 14 15 //先检查实例是否存在,如果不存在才进入下面的同步块 16 17 if(instance == null){ 18 19 //同步块,线程安全的创建实例 20 21 synchronized(Singleton.class){ 22 23 //再次检查实例是否存在,如果不存在才真的创建实例 24 25 if(instance == null){ 26 27 instance = new Singleton(); 28 29 } 30 31 } 32 33 } 34 35 return instance; 36 37 } 38 39 }
优点:懒加载,线程安全。
注:实例必须有 volatile 关键字修饰,其保证初始化完全。
饿汉模式
1 public class Singleton { 2 3 //4:定义一个静态变量来存储创建好的类实例 4 5 //直接在这里创建类实例,只会创建一次 6 7 private static Singleton instance = new Singleton(); 8 9 //1:私有化构造方法,好在内部控制创建实例的数目 10 11 private Singleton(){ 12 13 } 14 15 //2:定义一个方法来为客户端提供类实例 16 17 //3:这个方法需要定义成类方法,也就是要加static 18 19 //这个方法里面就不需要控制代码了 20 21 public static Singleton getInstance(){ 22 23 //5:直接使用已经创建好的实例 24 25 return instance; 26 27 } 28 29 }
优点:饿汉模式天生是线程安全的,使用时没有延迟。
缺点:启动时即创建实例,启动慢,有可能造成资源浪费。
Holder模式
1 public class Singleton { 2 /** 3 * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 4 * 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 5 */ 6 private static class SingletonHolder{ 7 /** 8 * 静态初始化器,由JVM来保证线程安全 9 */ 10 private static Singleton instance = new Singleton(); 11 } 12 /** 13 * 私有化构造方法 14 */ 15 private Singleton(){ 16 } 17 public static Singleton getInstance(){ 18 return SingletonHolder.instance; 19 } 20 }
优点:将懒加载和线程安全完美结合的一种方式(无锁)。(推荐)
备注:
- 全局共享,独一份;
- 构造函数不暴露(如果暴露便不能保证一份),自己负责自己的构造;
- 懒汉式:Lazy load,用到才加载,非线程安全。如何保证线程安全呢:
(1) synchronized getInstance()。
(2)双重检查加锁(volatile)。
- 饿汉式:一开始就申请好,浪费了点资源,但其线程安全。
- Holder模式:
(1)改成内部类,由JVM保证线程安全性。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JAVA设计模式(2)建造者模式
1 定义 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 类型:创建类模式。 四个要素: 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。 建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。 导演类:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。 2 代码实现 class Product { private String name; private String type; public void showProduct(){ System.out.println(“名称:”+name); S...
- 下一篇
Java设计模式之单例模式的9种方法
一. 什么是单例模式 因进程需要,有时我们只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计。 二. 单例模式的特点 1、单例模式只能有一个实例。 2、单例类必须创建自己的唯一实例。 3、单例类必须向其他对象提供这一实例。 三. 单例模式VS静态类 在知道了什么是单例模式后,我想你一定会想到静态类,“既然只使用一个对象,为何不干脆使用静态类?”,这里我会将单例模式和静态类进行一个比较。 1、单例可以继承和被继承,方法可以被override,而静态方法不可以。 2、静态方法中产生的对象会在执行后被释放,进而被GC清理,不会一直存在于内存中。 3、静态类会在第一次运行时初始化,单例模式可以有其他的选择,即可以延迟加载。 4、基于2, 3条,由于单例对象往往存在于DAO层(例如sessionFactory),如果反复的初始化和释放,则会占用很多资源,而使用单例模式将其常驻于内存可以更加节约资源。 5、静态方法有更高的访问效率。 6、单例模式很容易被测试。 几个关于静态类的误解: 误解一:静态方法常驻内存而实例方法不...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS8安装Docker,最新的服务器搭配容器使用
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2全家桶,快速入门学习开发网站教程