1 package concurrent; 2 3 /** 4 * 单例设计模式与多线程 (1)立即加载与饿汉模式 (2)延迟加载与懒汉模式(3)内置静态类实现单例设计模式 5 * (4)枚举类实现单例设计模式 6 * 7 * @author foolishbird_lmy 8 * 9 */ 10 class SingletonA { 11 // 立即加载与饿汉模式 12 private static SingletonA sa = new SingletonA(); 13 14 private SingletonA() { 15 16 } 17 18 public static SingletonA getInstance() { 19 return sa; 20 } 21 } 22 23 class SingletonB { 24 // 延迟加载与懒汉模式,双检查模式 25 private static SingletonB sb; 26 27 private SingletonB() { 28 29 } 30 31 public static SingletonB getInstance() { 32 // 延迟加载 33 if (sb == null) { 34 synchronized (SingletonB.class) { 35 if (sb == null) { 36 sb = new SingletonB(); 37 } 38 } 39 } 40 return sb; 41 } 42 } 43 44 class SingletonC { 45 //内部类 46 private static class SingletonHandler{ 47 private static SingletonC sc = new SingletonC(); 48 } 49 50 private SingletonC(){ 51 52 } 53 54 public static SingletonC getInstance(){ 55 return SingletonHandler.sc; 56 } 57 } 58 59 enum SingletonD{ 60 //使用enum枚举类实现单例模式 61 INSTANCE; 62 public void get(){ 63 System.out.println(); 64 } 65 } 66 class SingletonThread extends Thread { 67 public void run() { 68 System.out.println(SingletonA.getInstance().hashCode()); 69 System.out.println(SingletonB.getInstance().hashCode()); 70 System.out.println(SingletonC.getInstance().hashCode()); 71 System.out.println(SingletonD.INSTANCE.hashCode()); 72 } 73 } 74 75 public class TestSingleton { 76 public static void main(String[] args) { 77 SingletonThread st1 = new SingletonThread(); 78 SingletonThread st2 = new SingletonThread(); 79 SingletonThread st3 = new SingletonThread(); 80 st1.start(); 81 st2.start(); 82 st3.start(); 83 } 84 }
1、恶汉:因为加载类的时候就创建实例,所以线程安全(多个ClassLoader存在时例外)。缺点是不能延时加载。
2、懒汉:需要加锁才能实现多线程同步,但是效率会降低。优点是延时加载。
3、双重校验锁:麻烦,在当前Java内存模型中不一定都管用,某些平台和编译器甚至是错误的,因为sb = new SingletonB()这种代码在不同编译器上的行为和实现方式不可预知。
4、静态内部类:延迟加载,减少内存开销。因为用到的时候才加载,避免了静态field在单例类加载时即进入到堆内存的permanent代而永远得不到回收的缺点(大多数垃圾回收算法是这样)。
5、枚举:很好,不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。
时间: 2024-10-09 09:07:32