设计模式 –单例模式

it2023-10-31  76

1 概念

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。 实现方法: (1) 构造器私有化 。 (2) 类的内部创建对象。 (3) 向外暴露一个静态的公共方法。

2 饿汉式

优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。 缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费

public class HungrySingleton { private static final HungrySingleton hungrySingleton = new HungrySingleton(); private HungrySingleton() { } public static HungrySingleton getInstance(){ return hungrySingleton; } }

3 懒汉式

懒汉式单例的特点是:被外部类调用的时候内部类才会加载

3.3 类锁

public class LazySingleton { private static LazySingleton lazySingleton = null; private LazySingleton() { } /** * 类锁,线程安全,锁粒度较高 */ public static synchronized LazySingleton getInstance() { if (lazySingleton == null) { lazySingleton = new LazySingleton(); } return lazySingleton; } }

3.2 双重检查

public class LazyDoubleCheckSingleton { private static LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null; private LazyDoubleCheckSingleton() { } /** * 双重检查,类锁,锁粒度较低 */ public static LazyDoubleCheckSingleton getInstance() { if (lazyDoubleCheckSingleton == null) { synchronized (LazyDoubleCheckSingleton.class) { if (lazyDoubleCheckSingleton != null) { return lazyDoubleCheckSingleton; } lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton(); return lazyDoubleCheckSingleton; } } return lazyDoubleCheckSingleton; } }

3.3 内部类

public class LazyInnerClassSingleton { private LazyInnerClassSingleton() { } /** * 内部类特性,当外部调用时,内部类初始化 */ public static LazyInnerClassSingleton getInstance() { return Lazyholder.LAZY; } private static class Lazyholder { private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton(); } }

PS: 反射破坏单例模式

public class ReflectDestoryDemo { public static void main(String[] args) throws Exception { Class<?> clazz = LazyDoubleCheckSingleton.class; Constructor<?> constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); Object o1 = constructor.newInstance(); LazyDoubleCheckSingleton o2 = LazyDoubleCheckSingleton.getInstance(); System.out.println(o1 == o2); } }

4 注册式单例

public class ContainerSingleton { private ContainerSingleton() { } private static Map<String, Object> ioc = new ConcurrentHashMap<>(); public static Object getBean(String className) { synchronized (ioc) { if (!ioc.containsKey(className)) { Object obj = null; try { obj = Class.forName(className).newInstance(); ioc.put(className, obj); } catch (Exception e) { e.printStackTrace(); } } return ioc.get(className); } } }

5 JDK 源码

最新回复(0)