文章目录
- 一、对比总览
- 详细解释
- 二、代码
- 1. 饿汉式
- 2. 饱汉式
- 3. 饱汉式-双检锁
- 4. 静态内部类
- 5. 枚举单例
- 三、性能对比
一、对比总览
以下是不同单例模式实现方式的特性对比表格。表格从线程安全性、延迟加载、实现复杂度、反序列化安全性、防反射攻击性等多个方面进行考量。
特性 | 饿汉式 | 饱汉式 | 饱汉式-双检锁 | 静态内部类 | 枚举单例 |
---|---|---|---|---|---|
线程安全性 | √ | × | √ | √ | √ |
延迟加载 | × | √ | √ | √ | × |
实现复杂度 | √ | √ | × | √ | √ |
反序列化安全性 | × | × | × | × | √ |
防反射攻击性 | × | × | × | × | √ |
详细解释
-
线程安全性:
- 饿汉式:类加载时即创建实例(因为instance是static),线程安全。
- 饱汉式:未使用同步机制,线程不安全。
- 饱汉式-双检锁:使用同步块和双重检查锁,线程安全。
- 静态内部类:通过类加载机制,线程安全。
- 枚举单例:JVM确保线程安全。
-
延迟加载:
- 饿汉式:类加载时即创建实例,不具备延迟加载。
- 饱汉式:实例在首次使用时创建,具备延迟加载。
- 饱汉式-双检锁:实例在首次使用时创建,具备延迟加载。
- 静态内部类:实例在首次使用时创建(因为静态内部类只有在使用时才会加载),具备延迟加载。
- 枚举单例:类加载时即创建实例,不具备延迟加载。
-
实现复杂度:
- 饿汉式:实现简单。
- 饱汉式:实现简单。
- 饱汉式-双检锁:实现相对复杂。
- 静态内部类:实现简单。
- 枚举单例:实现简单。
-
反序列化安全性:
- 饿汉式、饱汉式、饱汉式-双检锁、静态内部类:需要实现
readResolve
方法以防止反序列化创建新实例。 - 枚举单例:天然防止反序列化创建新实例,JVM保证。
- 饿汉式、饱汉式、饱汉式-双检锁、静态内部类:需要实现
-
防反射攻击性:
- 饿汉式、饱汉式、饱汉式-双检锁、静态内部类:可能通过反射创建新实例。
- 枚举单例:防止反射攻击,创建新实例时抛出
IllegalArgumentException
。
二、代码
1. 饿汉式
public class OrderManager1 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();@Getterprivate static final OrderManager1 instance = new OrderManager1();/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}
2. 饱汉式
public class OrderManager2 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();private static OrderManager2 instance;public static OrderManager2 getInstance(){if (instance == null){instance = new OrderManager2();}return instance;}/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}
3. 饱汉式-双检锁
public class OrderManager3 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();private static OrderManager3 instance;public static OrderManager3 getInstance(){if (instance == null){synchronized (OrderManager3.class){if (instance == null){instance = new OrderManager3();}}instance = new OrderManager3();}return instance;}/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}
4. 静态内部类
public class OrderManager4 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();private static class SingletonHelper{private static final OrderManager4 INSTANCE = new OrderManager4();}public static OrderManager4 getInstance(){return SingletonHelper.INSTANCE;}/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}
5. 枚举单例
public enum OrderManager5 {INSTANCE;@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}