Java 设计模式-【单例模式】

本文详细介绍了单例模式的概念及其应用场景,包括饿汉式、懒汉式、双重检索式及静态内部类式的实现方式,并对比了它们各自的优缺点。

单例解决了什么问题:为了节约系统资源,有时需要确保系统中某个类只有唯一一个实例,当这个唯一实例创建成功之后,我们无法再创建一个同类型的其他对象,所有的操作都只能基于这个唯一实例。为了确保对象的唯一性,我们可以通过单例模式来实现,这就是单例模式的动机所在。

单例的应用场景:一般是对于那些业务逻辑上限定不能多例只能单例的情况,例如:类似于计数器之类的存在,一般都需要使用一个实例来进行记录,若多例计数则会不准确。

 

 

饿汉式:

  条件:

  1. 构造器私有化
  2. 本类对象作为本类的属性存在 用static 修饰保证只加载一次,不会重复创建对象
  3. 公共的静态的方法可以通过该方法拿到属性

   优缺点:

    优点:安全

    缺点:可能会导致对象创建过早

 1 package com.设计模式;
 2 
 3 /**
 4  * 饿汉式
 5  */
 6 public class ObjectShow1 {
 7     public static int i = 123;
 8     //静态私有成员,类在加载初期完成初始化;同时带来加载过早的问题
 9     private static ObjectShow1 objectShow1 = new ObjectShow1();
10 
11     private ObjectShow1() {
12         //私有构造函数,只能被列对象初始化
13         System.out.println(i);
14     }
15 
16     //使用public对外开放获取本类对象
17     public static ObjectShow1 getObjectShow1() {
18         return objectShow1;
19     }
20 }
View Code

 

 

懒汉式:

       条件:

  1. 构造器私有化
  2. 本类对象作为本类的属性存在 static 修饰 但是不进行初始化
  3. 公共的静态方法 并且判断是否给属性赋值

优缺点:

    优点:对象总是被需要的时候才被创建 解决了可能加载时机过早的问题

    缺点:在线程初期 线程不安全

 1 package com.设计模式;
 2 
 3 /**
 4  * 懒汉式
 5  */
 6 public class ObjectShow2 {
 7     public static int i = 123;
 8     //静态私有成员,不用构造器进行初始化
 9     private static ObjectShow2 objectShow2 = null;
10 
11     private ObjectShow2() {
12         //私有构造函数,只能被列对象初始化
13         System.out.println(i);
14     }
15 
16     //使用public对外开放获取本类对象,只有调用方法才会进行初始化
17     public static ObjectShow2 getObjectShow2() {
18         if (objectShow2 == null) {
19             objectShow2 = new ObjectShow2();
20         }
21         return objectShow2;
22     }
23 }
View Code

 

 

双重检索式:

       条件:

       1.构造器私有化

       2.本类的对象作为奔雷的属性存在 static 修饰 但不进行初始化

       3.公共的静态方法 并且判断是否给属性赋值

优缺点:

    程序的前期 线程不安全

    Synchronized 锁

    Synchronized 代码块 要求同一时间只有一个线程进入代码块区域

    因为jvm内存模型的原因 双重检索 也会有微小的可能发生问题

 1 package com.设计模式;
 2 
 3 /**
 4  * 双重检索式
 5  */
 6 public class ObjectShow3 {
 7     public static int i = 123;
 8     //静态私有成员,不用构造器进行初始化
 9     private static ObjectShow3 objectShow3;
10 
11     private ObjectShow3() {
12         //私有构造函数,只能被列对象初始化
13         System.out.println(i);
14     }
15 
16     //使用public对外开放获取本类对象,只有调用方法才会进行初始化
17     public static ObjectShow3 getObjectShow3() {
18         if (objectShow3 == null) {
19             //同步块,线程安全的创建实例
20             synchronized (ObjectShow3.class) {
21                 //再次检查实例是否存在,不在才创建
22                 if (objectShow3 == null)
23                     objectShow3 = new ObjectShow3();
24             }
25         }
26         return objectShow3;
27     }
28 }
View Code

 

 

静态内部类式:

条件:

       1.定义一个静态内部类

       2.外部类构造器私有化

       3.外部类的对象 作为内部类的属性存在 static 修饰 进行初始化

       4.公共的静态方法

优缺点:

    解决了,对象创建时机过早的问题

    没有产生线程安全问题

 1 package com.设计模式;
 2 
 3 /**
 4  * 静态内部类式
 5  */
 6 public class ObjectShow4 {
 7     public static int i = 123;
 8 
 9     static class InitObjectShow {
10         private static ObjectShow4 os = new ObjectShow4();
11 
12         public static ObjectShow4 getObj() {
13             return os;
14         }
15     }
16 
17     private ObjectShow4() {
18         System.out.println("ObjectShow4.ObjectShow4");
19     }
20 
21     public void show() {
22         System.out.println("ObjectShow4.show");
23     }
24 }
View Code

 

转载于:https://www.cnblogs.com/shwang/p/9325666.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值