单例模式的理解
一、什么是單例模式
單例模式的作用是保證應用程序在任何時刻只存在一個單例對象,比如打印機,一旦開始打印了就不再接收其他打印任務,一直到當前任務結束,否則會出現打印出的東西里存在多個任務中的信息;
二、單例的特征
[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 }?
轉載于:https://www.cnblogs.com/zyypro/p/7810103.html
總結
- 上一篇: composer 更新国内镜像地址
- 下一篇: 关于网页乱码和字符编码方式