单例模式8中实现方式

  • 1.单例模式介绍
  • 2.单例模式的八种方式
  • 3.饿汉式(静态常量),这种单例模式可用,可能造成内存浪费。
  • 4.饿汉式(静态代码块),这种单例模式可用,可能造成内存浪费。
  • 5.懒汉式(线程不安全),在实际开发中,不要使用这种方式。
  • 6.懒汉式(线程安全,同步方法),在实际开发中,不要使用这种方式。
  • 7.懒汉式(线程安全,同步代码块),不能使用
  • 8.双重检查,推荐使用
  • 9.静态内部类,推荐使用
  • 10.枚举,推荐使用
  • 11.单例模式使用
  • 12.单例模式注意事项和细节说明

1.单例模式介绍

单例模式:就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象的实例,并且该类之提供一个取得其对象实例的方法(静态方法)。

比如Hibernate的SessionFactory,它充当数据存储的代理,并负责创建Session对象。
SessionFactory不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory就够,这时候就会使用到单例模式。

2.单例模式的八种方式

1.饿汉式(静态常量)
2.饿汉式(静态代码块)
3.懒汉式(线程不安全)
4.懒汉式(线程安全,同步方法)
5.懒汉式(线程安全,同步代码块),解决不了线程安全问题,不能使用
6.双重检查 ,推荐使用
7.静态内部类 ,推荐使用
8.枚举, 推荐使用

3.饿汉式(静态常量),这种单例模式可用,可能造成内存浪费。

步骤:

1.构造器私有化(防止 new)

2.类的内部创建对象

3.向外暴露一个静态的公共方法,getInstance

话不多说,上代码

package singleton.type1;public class Singleton01 {public static void main(String[] args) {// 测试Singleton instance = Singleton.getIntance();Singleton instance2 = Singleton.getIntance();System.out.println(instance == instance2);System.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}}
// 饿汉式,(静态变量)class Singleton {private Singleton(){}private final static Singleton instance = new Singleton();public static Singleton getIntance (){return instance;}
}

运行一下

true
instance.hashCode=366712642
instance2.hashCode=366712642

优缺点分析

1.优点:写法简单,在类装载的时候去完成实例化。避免了线程同步的问题。

2.缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终都未使用过这个实例,就会造成资源的浪费。

3.这种方式基于classloder机制避免了多线程的同步问题,不过,instance在类装载时就实例化,在单例模式中大多数都是调用getInstance方法。

但是导致类装载的原因有很多,因此不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance就没有达到lazy loading的效果。

4.结论:这种单例模式可用,可能造成内存浪费。

4.饿汉式(静态代码块),这种单例模式可用,可能造成内存浪费。

话不多说,上代码

package singleton.type2;public class Singleton02 {public static void main(String[] args) {// 测试Singleton instance = Singleton.getIntance();Singleton instance2 = Singleton.getIntance();System.out.println(instance == instance2);System.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}}
// 饿汉式,(静态代码块)class Singleton {private Singleton(){}private final static Singleton instance;static {instance = new Singleton();}public static Singleton getIntance (){return instance;}
}

执行一下

true
instance.hashCode=366712642
instance2.hashCode=366712642

优缺点分析

1.这种方式和上面的方式类似,只不过将类实例化的过程放在了静态代码块中,也是类装载的时候,就执行代码块中的代码,初始化类的实例。优缺点和上面是一样的。

结论:这种单例模式可用,但是可能早成内存浪费。

5.懒汉式(线程不安全),在实际开发中,不要使用这种方式。

package singleton.type3;public class Singleton03 {public static void main(String[] args) {// 测试System.out.println("懒汉式,线程不安全");Singleton instance = Singleton.getIntance();Singleton instance2 = Singleton.getIntance();System.out.println(instance == instance2);System.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}}
// 饿汉式,(线程不安全)class Singleton {private Singleton(){}private static Singleton instance;// 提供一个静态共有方法,当使用该方法时,才去创建intancepublic static Singleton getIntance (){if (instance == null){instance = new Singleton();}return instance;}
}

执行一下

懒汉式,线程不安全
true
instance.hashCode=366712642
instance2.hashCode=366712642

优缺点分析:

1.起到了Lazy Loading的效果,但是只能在单线程下使用。

2.如果在多线程下,一个线程进入了 if (instance == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可使用这种方式。

3.在实际开发中,不要使用这种方式。

6.懒汉式(线程安全,同步方法),在实际开发中,不要使用这种方式。

package singleton.type4;public class Singleton04 {public static void main(String[] args) {// 测试System.out.println("懒汉式2,线程安全");Singleton instance = Singleton.getIntance();Singleton instance2 = Singleton.getIntance();System.out.println(instance == instance2);System.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}}
// 懒汉式,(线程安全,同步方法)class Singleton {private Singleton(){}private static Singleton instance;// 提供一个静态共有方法,加入同步代码,解决线程安全问题public static synchronized Singleton getIntance (){if (instance == null){instance = new Singleton();}return instance;}
}

执行一下

懒汉式2,线程安全
true
instance.hashCode=366712642
instance2.hashCode=366712642

优缺点分析

1.解决了线程不安全问题

2.效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。
而这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低。

3.结论:在实际开发中,不推荐使用这种方式。

7.懒汉式(线程安全,同步代码块),不能使用

package singleton.type5;public class Singleton05 {public static void main(String[] args) {// 测试System.out.println("懒汉式2,线程不安全");Singleton instance = Singleton.getIntance();Singleton instance2 = Singleton.getIntance();System.out.println(instance == instance2);System.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}}
// 懒汉式,(线程安全,同步代码块)class Singleton {private Singleton(){}private static Singleton instance;// 解决不了线程安全问题,没有实际意义public static Singleton getIntance (){if (instance == null){synchronized (Singleton.class){instance = new Singleton();}}return instance;}
}

优缺点分析

  1. 这种方式,本意是相对第四种实现方式的改进,因为前面同步方法效率太低,改为同步产生实力话的代码块。
  2. 但是这种同步并不能起到线程同步的作用。跟第3种实现方式遇到的情形一致,假如一个线程进入了if (instance == null)的判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。
  3. 结论:在实际开发种,不能使用这种方式。

8.双重检查,推荐使用

package singleton.type6;public class Singleton06 {public static void main(String[] args) {// 测试System.out.println("双重检测,线程安全");Singleton instance = Singleton.getIntance();Singleton instance2 = Singleton.getIntance();System.out.println(instance == instance2);System.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}}
// 双重检测,推荐使用class Singleton {private Singleton(){}private static volatile Singleton instance;// 提供一个静态共有方法,加入双重检测代码,解决线程安全问题,同时解决懒加载问题// 同时保证了效率,推荐使用public static Singleton getIntance (){if (instance == null){synchronized (Singleton.class){if (instance == null){instance = new Singleton();}}}return instance;}
}

优缺点分析

  1. 双重检测概念是多线程开发中常使用到的,如代码所示,我们进行了两次if (instance == null)检查,这也就可以保证线程安全了。
  2. 这样,实例化代码只用执行一次,后面再次访问时,判断if (instance == null),直接return实例化对象,也避免了反复惊醒方法同步。
  3. 线程安全;延迟加载,效率较高。
  4. 结论:在实际开发中,推荐使用这种单例设计模式。

9.静态内部类,推荐使用

package singleton.type7;public class Singleton07 {public static void main(String[] args) {// 测试System.out.println("使用静态内部类完成单例模式");Singleton instance = Singleton.getIntance();Singleton instance2 = Singleton.getIntance();System.out.println(instance == instance2);System.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}}
// 双重检测,推荐使用class Singleton {// 构造器私有化private Singleton(){}//写一个静态内部类,该类中有一个静态属性Singletonprivate static class SingletonInstance{private static volatile Singleton instance = new Singleton();}// 提供一个静态的共有方法,直接返回SingletonInstance.instance;public static Singleton getIntance (){return SingletonInstance.instance;}
}

优缺点分析

  1. 这种方式采用了类装载的机制来保证初始胡实例时只有一个线程。
  2. 静态内部类方式在Singleton类装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成了Singleton的实例化。
  3. 类的静态属性只有在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程时无法进入的。
  4. 优点:避免了线程不安全,利用静态内部类特点实现延迟加载,效率高
  5. 结论:推荐使用。

10.枚举,推荐使用

package singleton.type8;public class Singleton08 {public static void main(String[] args) {// 测试System.out.println("使用枚举单例模式");Singleton instance = Singleton.INSTANCE;Singleton instance2 = Singleton.INSTANCE;System.out.println(instance == instance2);System.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());instance.sayOK();}
}
enum Singleton {INSTANCE; //属性。public void sayOK(){System.out.println("ok");}
}

优缺点分析

  1. 这借助了JDK1.5中添加的枚举来实现单例模式。不仅能够避免多线程同步问题,而且还能防止反序列化重新创建新的对象。
  2. 结论:推荐使用

11.单例模式使用

Runtime类,饿汉式,静态变量。

12.单例模式注意事项和细节说明

  1. 单例模式保证了系统内存中该类之存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
  2. 当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new
  3. 单例模式使用的场景:需要频繁进行创建和销毁的对象、创建对象耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件对象,比如数据源,session工厂等。

Java面试23种设计模式之单例模式的8种实现方式相关推荐

  1. Java23种设计模式之单例模式的五种实现方式、反射破解单例模式、不能破解枚举单例模式详解

    源码链接(Gitee码云):https://gitee.com/oldou/javadesignpatterns 这里有我整理好的Java23种设计模式的源码以及博客教程,博客教程中介绍了Java23 ...

  2. 《23种设计模式之单例模式(4种实现)》

    说在前头:本人为大二在读学生,书写文章的目的是为了对自己掌握的知识和技术进行一定的记录,同时乐于与大家一起分享,因本人资历尚浅,能力有限,文章难免存在一些错漏之处,还请阅读此文章的大牛们见谅与斧正.若 ...

  3. 3种设计模式java小程序_Java设计模式之单例模式(3种实现方式)

    饿汉模式 public class Singleton {//实例化private static Singleton instance=new Singleton();private Singleto ...

  4. java 23种设计模式 04 单例模式

    java 23种设计模式 04 单例模式 一.什么是单例模式 单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象.也就是说,在整个程序空间中,该类只存在一个实例对象.   ...

  5. Java设计模式之单例模式(七种写法)

    Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton {private static Singleton ...

  6. 24种设计模式之单例模式

    24种设计模式之单例模式  一.核心作用: 保证一个类只有一个实例,并且提供一个访问该实例的全局访问点. 二.常见的应用场景: 1.Windows的Task Manager(任务管理器)就是很典型的单 ...

  7. Java实现二十三种设计模式(五)—— 十一种行为型模式 (中)——解释器模式、迭代器模式、中介者模式、备忘录模式

    Java实现二十三种设计模式(五)-- 十一种行为型模式 (中)--解释器模式.迭代器模式.中介者模式.备忘录模式 一.解释器模式 我国 IT 界历来有一个汉语编程梦,虽然各方对于汉语编程争论不休,甚 ...

  8. 23种设计模式之单例模式、工厂模式、原型模式、建造者模式

    系列文章目录 第一章:程序设计原则-单一职责.接口隔离.依赖倒置.里式替换 第二章:程序设计原则-开闭原则.迪米特法则.合成复用原则 文章目录 系列文章目录 一.设计模式简单介绍 1.1.什么是设计模 ...

  9. Java的二十三种设计模式(单例模式、工厂方法模式、抽象工厂模式)

    从这一块开始,我们详细介绍Java中23种设计模式的概念,应用场景等情况,并结合他们的特点及设计模式的原则进行分析. 创建型模式(5种):用于描述"怎样创建对象",它的主要特点是& ...

最新文章

  1. 深度优先搜索 和问题 简单函数递归 “加 还是不加”
  2. Android中将布局文件/View添加至窗口过程分析 ---- 从setContentView()谈起
  3. php如何判断多文件上传,php多文件上传
  4. mysql怎么定位错误信息_Mysql主从复制异常,定位具体的SQL
  5. 创业三年来的一些感想 - 创业篇1
  6. android代码打开数据库,Android打开和关闭数据库
  7. JAVA设计模式 - 代理模式
  8. 视频播放器+android,Android视频播放器
  9. java 1.8 内存告警问题
  10. csv可以保存特殊字符_浅谈CSV注入漏洞
  11. 使用STL标准模板库实现的个人通讯录
  12. 重拾呐些記憶,前面の路,獨自繼續前往。
  13. 揭秘:云控系统运行原理,有效规避风控
  14. uwe5622 uwe5621ds 紫光展锐 wifi 移植的几个关键点:
  15. js如何让段落首行缩进2个字符
  16. Linux/UNIX系统编程手册gg
  17. CSR867x — Headset项目评估总结
  18. 人人转联盟官网?人人转联盟是真的吗?人人转联盟能赚钱吗?
  19. %在C语言计算中的用法
  20. C语言经典例题100道(辗转相除求最大公约数和最小公倍数)

热门文章

  1. npm 报错 Module build failed: Error: No PostCSS Config found in:
  2. xhtml html
  3. Delphi用指针读取数组某个元素
  4. 测试Word2013发布博客
  5. NOI2011 阿狸的打字机题解
  6. 山西职业技术学院计算机宿舍怎么样,山西职业技术学院宿舍怎么样
  7. (85)Vivado 多周期路径约束情况
  8. 遗传算法锦标赛选择java实现_java – 遗传算法锦标赛选择
  9. python mvc_python mvc设计模式(一)
  10. sparkstreaming监听hdfs目录如何终止_HDFS—HA高可用详解