確保一個類最多隻有一個實例,並提供一個全局訪問點。java
懶漢式單例模式:在類加載時不初始化。安全
餓漢式單例模式:在類加載時就完成了初始化,因此類加載比較慢,但獲取對象的速度快。多線程
1 /** 2 * 餓漢式單例模式(線程安全) 3 */ 4 public class Singleton { 5 //static單例變量 6 private static Singleton singleton = new Singleton(); 7 8 //私有的構造方法 9 private Singleton() { 10 11 } 12 13 //靜態方法爲調用者提供單例對象 14 public static Singleton getInstance() { 15 return singleton; 16 } 17 }
1 /** 2 * 懶漢式(線程不安全) 3 */ 4 public class Singleton2 { 5 private static Singleton2 instance = null; 6 7 private Singleton2() { 8 9 } 10 11 public static Singleton2 getInstance() { 12 if (instance == null) { 13 instance = new Singleton2(); 14 } 15 return instance; 16 } 17 }
1 /** 2 * 懶漢式(線程安全) 3 */ 4 public class Singleton3 { 5 private static Singleton3 instance = null; 6 7 private Singleton3() { 8 9 } 10 11 public static synchronized Singleton3 getInstance() { 12 if (instance == null) { 13 instance = new Singleton3(); 14 } 15 return instance; 16 } 17 }
1 /** 2 * 雙重校驗鎖(線程安全) 3 */ 4 public class Singleton4 { 5 private volatile static Singleton4 instance = null; 6 7 private Singleton4() { 8 9 } 10 11 /** 12 * 當第一次調用getInstance()方法時,instance爲空,同步操做,保證多線程實例惟一 13 * 當第一次後調用getInstance()方法時,instance不爲空,不進入同步代碼塊,減小了沒必要要的同步 14 */ 15 public static Singleton4 getInstance() { 16 if (instance == null) { 17 synchronized (Singleton4.class) { 18 if (instance == null) { 19 instance = new Singleton4(); 20 } 21 } 22 } 23 return instance; 24 } 25 }
1 /** 2 * 靜態內部類(線程安全) 3 */ 4 public class Singleton5 { 5 /** 6 * 靜態內部類 7 */ 8 private static class SingleHolder { 9 public static Singleton5 instance = new Singleton5(); 10 } 11 12 //第一次調用getInstance方法時,纔會去加載SingleHolder類,繼而實例化instance 13 public static Singleton5 getInstance() { 14 return SingleHolder.instance; 15 } 16 17 private Singleton5() { 18 19 } 20 }
/** * 靜態代碼塊(線程安全) */ public class Singleton6 { private Singleton6() { } private static Singleton6 instance = null; // 靜態代碼塊 static { instance = new Singleton6(); } public static Singleton6 getInstance() { return instance; } }
1 /** 2 * 枚舉(線程安全) 3 */ 4 public enum Singleton7 { 5 //枚舉實例的建立是線程安全的,任何狀況下都是單例(包括反序列化) 6 INSTANCE; 7 }
1 package com.wpx.singleton; 2 3 public class SingletonDemo implements Runnable { 4 public static void main(String[] args) { 5 SingletonDemo[] threads = new SingletonDemo[10]; 6 for (int i = 0; i < threads.length; i++) { 7 threads[i] = new SingletonDemo(); 8 } 9 10 for (int i = 0; i < threads.length; i++) { 11 new Thread(threads[i]).start(); 12 } 13 } 14 15 @Override 16 public void run() { 17 // System.out.println(Singleton.getInstance().hashCode());//餓漢式單例模式(線程安全) 18 // System.out.println(Singleton2.getInstance().hashCode());//懶漢式(線程不安全) 19 // System.out.println(Singleton3.getInstance().hashCode());//懶漢式(線程安全) 20 // System.out.println(Singleton4.getInstance().hashCode());//雙重校驗鎖(線程安全) 21 // System.out.println(Singleton5.getInstance().hashCode());//靜態內部類(線程安全) 22 // System.out.println(Singleton6.getInstance().hashCode());//靜態代碼塊(線程安全) 23 System.out.println(Singleton7.INSTANCE.hashCode());//枚舉(線程安全) 24 } 25 }
public class Runtime { private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() { return currentRuntime; } private Runtime() { } }