java定义派的大小_Java 单例(Singleton)模式

一、什么是单例模式:

单例模式是一种确保了一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。被实例化的类称为单例类。

二、单例模式的特点:

单例类只有一个实例。

单例类必须自行创建自己唯一的实例。

单例类必须给其他对象提供这个实例。

注意:虽然单例模式和单例类限定了只能有一个实例,但是作为单例模式的推广,可以推广到任意且有限多个实例的情况,这时候被称为多例模式和多例类。

三、单例模式的结构:

891d458ab62af5fafc220fc64db51fbf.png

一个单例类只有一个实例。

单例类的实例持有对自己的引用。

四、单例模式的实例化:

Java中单例模式有着自己的特点,具体表现在单例类的实例化上:

饿汉式单例类(静态常量):

1 /**

2 * 饿汉式(静态常量)3 *4 *@authorZhouDX5 *@since2019/3/4 22:12:286 */

7 public classHungerSingleton {8 private static final HungerSingleton SINGLETON= newHungerSingleton();9

10 /**

11 * 私有的默认构造函数12 */

13 privateHungerSingleton() {14 }15

16 /**

17 * 静态工厂方法18 */

19 public staticHungerSingleton getInstance() {20 returnSINGLETON;21 }22 }

Java中最简单的单例类,类的单例被声明为静态变量,在类加载时,调用类的私有构造函数,静态变量被实例化。

特点:

1.类的构造函数私有,避免了外界利用构造函数创建任意多的实例。

2.且由于构造函数私有,类不能被继承。

3.只能通过静态方法getInstance()来获取类的实例对象。

优点:

类装载的时候就完成实例化。避免了线程同步问题。

缺点:

在类装载的时候就完成实例化,没有达到延迟加载的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。

饿汉式单例类(静态代码块):

1 /**

2 * 饿汉式单例类(静态代码块)3 *4 *@authorZhouDX5 *@since2019/3/13 22:45:246 */

7 public classHungerSington_StaticCode {8 private staticHungerSington_StaticCode singleton;9

10 /**

11 * 静态代码块12 */

13 static{14 singleton= newHungerSington_StaticCode();15 }16

17 /**

18 * 私有构造函数19 */

20 privateHungerSington_StaticCode() {21 }22

23 /**

24 * 获取单例类实例的唯一接口25 *26 *@return单例类27 */

28 public staticHungerSington_StaticCode getInstance() {29 returnsingleton;30 }31 }

特点:

将单例类放在静态代码块中,也是类在加载时执行静态代码块中的代码,完成类的实例化,优缺点同静态常量。

汉懒式单例类(线程不安全):

1 /**

2 * 懒汉式(线程不安全)[不可用]3 *4 *@authorZhouDX5 *@since2019/3/13 22:52:246 */

7 public classLazySingleton_ThreadUnsafe {8 private staticLazySingleton_ThreadUnsafe singleton;9

10 /**

11 * 获取单例类实例12 *13 *@return单例类实例14 */

15 public staticLazySingleton_ThreadUnsafe getInstance() {16 if (null ==singleton) {17 singleton = newLazySingleton_ThreadUnsafe();18 }19

20 returnsingleton;21 }22 }

特点:

1.达到了延迟加载的目的,只有在单例类第一次被引用时将自己实例化。

2.在单线程下使用。

缺点:

在多线程的环境中,多个线程同时进入if (null == singleton) {},还未执行singleton = new LazySingleton_ThreadUnsafe()时,另一个线程也恰好进入这里,就会造成单例类多个实例,线程不安全,不可以再多线程的环境下使用。

懒汉式(线程安全,同步方法)

1 /**

2 * 懒汉式(线程安全,同步方法)3 *4 *@authorZhouDX5 *@since2019/3/4 22:23:026 */

7 public classLazySingleton {8 private static LazySingleton lazySingleton = null;9

10 /**

11 * 构造函数12 */

13 privateLazySingleton() {14 }15

16 /**

17 * 静态工厂方法,返回懒汉式实力类的唯一实例18 *19 *@return

20 */

21 public static synchronizedLazySingleton getInstance() {22 if (lazySingleton == null) {23 return lazySingleton = newLazySingleton();24 }25 returnlazySingleton;26 }27 }

特点:

使用了synchronized对静态工厂类方法进行了同步,安全处理多线程的问题。

缺点:

每个线程执行getInstance()方法都要进行同步,大大降低了执行的效率。且getInstance()只需要实例化一次就可以。

懒汉式(线程不安全,同步代码块)

1 /**

2 * 懒汉式(线程安全,同步代码块)3 *4 *@authorZhouDX5 *@since2019/3/13 23:12:086 */

7 public classLaSingleton_ThreadUnsafe {8 private staticLaSingleton_ThreadUnsafe singleton;9

10 /**

11 * 静态构造方法12 */

13 privateLaSingleton_ThreadUnsafe() {14 }15

16 /**

17 * 获取单例类实例18 *19 *@return单例类实例20 */

21 public staticLaSingleton_ThreadUnsafe getInstance() {22 if (null ==singleton) {23 synchronized (LaSingleton_ThreadUnsafe.class) {24 singleton = newLaSingleton_ThreadUnsafe();25 }26 }27 returnsingleton;28 }29 }

特点:

同步产生实例的代码块。

缺点:

假如一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。

懒汉式(双重检查):

1 /**

2 * 懒汉式(双重检查):3 *4 *@authorZhouDX5 *@since2019/3/13 23:24:276 */

7 public classLazySingleton_DoubleCheck {8 private static volatileLazySingleton_DoubleCheck singleton;9

10 /**

11 * 静态构造方法12 */

13 privateLazySingleton_DoubleCheck() {14 }15

16 /**

17 * 获取单例类实例18 *19 *@return单例类实例20 */

21 public staticLazySingleton_DoubleCheck getInstance() {22 if (null ==singleton) {23 synchronized (LazySingleton_DoubleCheck.class) {24 singleton = newLazySingleton_DoubleCheck();25 }26 }27 returnsingleton;28 }29 }

特点:

1.进行了两次if (singleton == null)检查,保证了线程安全。

2.实例化代码只执行一次,后面再次访问时,判断if (singleton == null),直接return实例化对象。

优点:

程安全;延迟加载;效率较高。

静态内部类:

1 /**

2 * 静态内部类3 *4 *@authorZhouDX5 *@since2019/3/13 23:28:586 */

7 public classSingleton_StaticInnerClass {8 /**

9 * 私有构造方法10 */

11 privateSingleton_StaticInnerClass() {12 }13

14 /**

15 * 静态内部类16 */

17 private static classSingletonInstance {18 private static final Singleton_StaticInnerClass SINGLETON = newSingleton_StaticInnerClass();19 }20

21 /**

22 * 获取单例类实例23 *24 *@return单例类实例25 */

26 private staticSingleton_StaticInnerClass getInstance() {27 returnSingletonInstance.SINGLETON;28 }29 }

特点:

类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。

优点:

避免了线程不安全,延迟加载,效率高。

枚举:

1 /**

2 * 枚举3 *4 *@authorZhouDX5 *@since2019/3/13 23:33:436 */

7 public enumSingleton_Enum {8 SINGLETON;9

10 public voidwhateverMethod() {11 }12 }

特点:

系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。

优点:

当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new,可能会给其他开发人员造成困扰,特别是看不到源码的时候。

懒汉式单例类与饿汉式单例类的比较:

饿汉式单例类在自己被加载时将自己实例化,即便加载器是静态的,依旧在加载时实例化自己;懒汉式单例类在第一次被引用时将自己实例化,如果加载器是静态的,懒汉式单例类被加载时不会将自己实例化。

从资源利用角度讲,懒汉式单例类的资源利用效率高点;从速度和反应时间来讲,饿汉式的好点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值