1 //饿汉式:资源利用率较低(无论是否需要都会创建),性能较高(使用前无需判断实例是否存在,可直接使用) 2 public class EagerSingleton{ 3 private static final EagerSingleton instance=new EagerSingleton(); 4 private EagerSingleton(){} 5 public static EagerSingleton getInstance(){ 6 return instance; 7 } 8 }
1 //懒汉式:资源利用率较高(需要时才创建),性能较低(需要判断实例是否存在) 2 public class LazySingleton{ 3 private static LazySingleton instance; 4 private LazySingleton(){} 5 synchronized/*同步很重要,保证多线程时安全*/ public static LazySingleton getInstance(){ 6 if(instance==null){ 7 instance=new LazySingleton(); 8 } 9 return instance; 10 } 11 }
1 //这是个错误示例:双重检查成例对java语言编译器不成立,在线程1进入第2个if时,引用instance被创建, 2 //但可能未来得及被实例化,此时线程2在第1个if时判断引用instance不为空则直接返回instance,但JDK不允许 3 //返回一个没有实例化的对象,所有会导致系统崩溃。 4 public class LazySingleton{ 5 private static LazySingleton instance; 6 private LazySingleton(){} 7 public static LazySingleton getInstance(){ 8 if(instance==null){ 9 synchronized(LazySingleton.class){ 10 if(instance==null){ 11 System.out.println("LazySingleton.getInstance()"); 12 instance=new LazySingleton(); 13 } 14 } 15 } 16 return instance; 17 } 18 }
1 package com.tn.pattern; 2 3 import java.util.HashMap; 4 5 public class Client { 6 public static void main(String[] args) throws Exception { 7 RegSingleton.getInstance(null).print(); 8 RegSingletonChild.getInstance().print(); 9 } 10 } 11 12 //登记式 13 class RegSingleton{ 14 private static HashMap singletons=new HashMap(); 15 static{ 16 RegSingleton instance=new RegSingleton(); 17 singletons.put(instance.getClass().getName(), instance); 18 } 19 20 protected RegSingleton(){} 21 22 public static RegSingleton getInstance(String name){ 23 if(name==null) 24 name="com.tn.pattern.RegSingleton"; 25 if(singletons.get(name)==null){ 26 try { 27 singletons.put(name, Class.forName(name).newInstance()); 28 } catch (Exception e) { 29 e.printStackTrace(); 30 } 31 } 32 return (RegSingleton)singletons.get(name); 33 } 34 public void print(){ 35 System.out.println("RegSingleton.print()"); 36 } 37 } 38 39 class RegSingletonChild extends RegSingleton{ 40 public RegSingletonChild(){} 41 42 public static RegSingletonChild getInstance(){ 43 return (RegSingletonChild)RegSingleton.getInstance("com.tn.pattern.RegSingletonChild"); 44 } 45 46 public void print(){ 47 System.out.println("RegSingletonChild.print()"); 48 } 49 }