单例模式的理解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式的理解相关的知识,希望对你有一定的参考价值。

一、什么是单例模式

  单例模式的作用是保证应用程序在任何时刻只存在一个单例对象,比如打印机,一旦开始打印了就不再接收其他打印任务,一直到当前任务结束,否则会出现打印出的东西里存在多个任务中的信息;

二、单例的特征

  [1] 单例只能有一个实例;

  [2] 单例只能自己实例化唯一实例;

  [3]单例必须向其他对象提供这一实例;

三、常见单例的模式

  [1]饿汉式:不管其他对象需不需要单例的唯一实例,我都先完成实例化,你要就拿不用就放那;

 1 package com.zyy.stop;
 2 
 3 public class Zyyprotest {
 4     
 5     public static void main(String[] args) {
 6         SingleTon1.getSingleTon();
 7     }
 8 }
 9 
10 class SingleTon1 {
11     
12     private SingleTon1 () {}
13     
14     //不管需不需要,先创建再说
15     static SingleTon1 st1 = new SingleTon1();
16     
17     public static SingleTon1 getSingleTon() {
18         return st1;
19     }
20 }

  [2]懒汉式:外部需要唯一实例,不存在才会去创建;

 1 package com.zyy.stop;
 2 
 3 public class Zyyprotest {
 4     
 5     public static void main(String[] args) {
 6         SingleTon2.getSingleTon();
 7     }
 8 }
 9 
10 class SingleTon2 {
11     
12     private SingleTon2 () {}
13     
14     
15     static SingleTon2 st2 = null;
16     
17     public static SingleTon2 getSingleTon() {
18         //不存在才会去创建
19         if (st2 == null)
20             st2 = new SingleTon2();
21         
22         return st2;
23     }
24 }

  [3] 登记式:创建过唯一实例后,将该实例登记到Map中,下次用的直接从Map中获取;

 1 package com.zyy.stop;
 2 
 3 import java.util.Map;
 4 
 5 import org.apache.commons.collections4.map.HashedMap;
 6 
 7 public class Zyyprotest {
 8     
 9     public static void main(String[] args) throws InstantiationException, IllegalAccessException,
10         ClassNotFoundException {
11         SingleTon3.getSingleTon("SingleTon3");
12     }
13 }
14 
15 class SingleTon3 {
16     
17     private static Map<String, SingleTon3> map = new HashedMap<String, SingleTon3>();
18     
19     protected SingleTon3 () {}
20     
21     public static SingleTon3 getSingleTon(String name) throws InstantiationException, IllegalAccessException,
22         ClassNotFoundException {
23         
24         if (name == null)
25             name = SingleTon3.class.getName();
26         
27         if (map.get(name) == null)
28             map.put(name, (SingleTon3)Class.forName(name).newInstance());
29         
30         return map.get(name);
31     }
32 }

四、双重检查锁

   这里我们用懒汉式来介绍双重检查锁,

 1 class SingleTon2 {
 2     
 3     private SingleTon2() {}
 4     
 5     static SingleTon2 st2 = null;
 6     
 7     public static SingleTon2 getInstaTon2 () {
 8         if (st2 == null)
 9             st2 = new SingleTon2();
10         
11         return st2;
12     }
13 }

在getInstaTon2 ()方法中有一步判断是否为空的操作,比如现在有2个线程A与B,同时到达判断这一步,在这一瞬间实例并没有创建,所以他们都能通过判断去创建2个实例,这就与单例的唯一实例相违背了;

但是我们通过双重检查锁就可以规避这种极端的情况:

 1 class SingleTon2 {
 2     
 3     private SingleTon2() {}
 4     
 5     static SingleTon2 st2 = null;
 6     
 7     public static SingleTon2 getInstaTon2 () {
 8         if (st2 == null) {
 9             synchronized (st2) {
10                 if (st2 == null) 
11                     st2 = new SingleTon2();
12             }
13         }
14         
15         return st2;
16     }
17 }

 

以上是关于单例模式的理解的主要内容,如果未能解决你的问题,请参考以下文章

单例模式的理解

程序员要透彻理解单例模式

我理解的单例设计模式

单例模式还可以这样理解哦

深入理解设计模式-单例模式

深入理解设计模式-单例模式(饿汉单例模式懒汉单例模式双锁单例模式)