概念:
JAVA中單例模式是一種常見的設計模式,單例模式的寫法有不少種,這裏主要介紹三種:懶漢式單例、餓漢式單例。單例模式有以下特色:
一、單例類只能有一個實例。
二、單例類必須本身建立本身的惟一實例。
三、單例類必須給全部其餘對象提供這一實例。java
單例模式確保某個類只有一個實例,且自行實例化向整個系統提供這個實例。在系統中線程池、日誌對象、打印機、公用方法等被設計成單例。歸根結底就是單例模式確保不一致狀態。設計模式
1、懶漢試單例安全
一、懶漢(線程不安全)多線程
package com.example.Controller; /** * Title:懶漢(線程不安全) * Author:Administrator * Time:2017/5/8 0008 */ public class Singleton { private static Singleton singleton; private Singleton(){} //懶漢(線程不安全) public static Singleton getInstance() { if (singleton == null){ singleton = new Singleton(); } return singleton; } }
二、懶漢(線程安全)性能
package com.example.Controller; /** * Title:懶漢(線程安全) * Author:Administrator * Time:2017/5/8 0008 */ public class Singleton { private static Singleton singleton; private Singleton(){} //懶漢(線程安全) public static synchronized Singleton getSingleton() { if (singleton == null){ singleton = new Singleton(); } return singleton; } }
三、雙重檢查鎖定spa
package com.example.Controller; /** * Title:雙重檢查鎖定 * Author:Administrator * Time:2017/5/8 0008 */ public class Singleton { private static Singleton singleton; private Singleton(){} //雙重檢查鎖定 public static synchronized Singleton getSingleton() { if (singleton == null){ synchronized(Singleton.class){ if (singleton == null){ singleton = new Singleton(); } } } return singleton; } }
四、靜態內部類建立懶漢(線程安全)線程
package com.example.Controller; /** * Title:靜態內部類建立懶漢(線程安全) * Author:Administrator * Time:2017/5/8 0008 */ public class Singleton { //靜態內部類建立懶漢(線程安全) private static class LazyHolder{ private static final Singleton INSTANCE = new Singleton(); } private Singleton(){} public static Singleton getInstance(){ return LazyHolder.INSTANCE; } }
這種比上面一、二、3都好一些,既實現了線程安全,又避免了同步帶來的性能影響。設計
2、餓漢式單例日誌
package com.example.Controller; /** * Title:餓漢(線程安全) * Author:Administrator * Time:2017/5/8 0008 */ public class Singleton { //餓漢(天生線程安全) private Singleton(){} private static final Singleton instance = new Singleton(); //靜態工程方法 public static Singleton getInstance(){ return instance; } }
餓漢式在類初始化時就建立好了一個靜態對象供系統使用,因此餓漢式天生就是線程安全的。code
3、枚舉
public enum Singleton { INSTANCE; public void whateverMethod() { } }
它不只能避免多線程同步問題,並且還能防止反序列化從新建立新的對象,我的認爲因爲jdk1.5中才加入enum特性,用這種方式寫難免讓人感受生疏,在實際工做中,也不多看見有人這麼寫過。