Java设计模式 单例设计模式

单例设计模式

常见的五种单例模式实现方式– 主要:

  • 饿汉式(线程安全,调用效率高。 但是,不能延时加载。)
  • 懒汉式(线程安全,调用效率不高。 但是,可以延时加载。)
  • 其他:
    • 双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题。不建议使用)
    • 静态内部类式(线程安全,调用效率高。 但是,可以延时加载)
    • 枚举式(线程安全,调用效率高,不能延时加载。并且可以天然的防止反射和反序列化漏洞!)
  • 如何选用?
    • 单例对象 占用 资源 少,不需要 延时加载
      • 枚举式 好于 饿汉式
    • 单例对象 占用 资源 大,需要 延时加载:
      • 静态内部类式 好于 懒

饿汉

public class OneObject {

	private static final OneObject OBJECT = new OneObject();
	
	private OneObject () {}
	
	public static OneObject build () {
		return OBJECT;
	}
	
}

懒汉

public class OneObjectLaz {
	
	private static OneObjectLaz laz;
	
	private OneObjectLaz () {}
	
	public static OneObjectLaz build () {
		synchronized (OneObjectLaz.class) {
			if (null == laz) laz = new OneObjectLaz();
		}
		
		return laz;
	}
	
}

多线程测试

for (int i = 0; i < 10; i++) {
    new Thread(() -> {
        OneObjectLaz build = OneObjectLaz.build();
        System.out.println(build.hashCode());
    }).start();
}

通过反射机制暴力范围 private 构造器, 从而达到多实例

Constructor<OneObject> constructor = OneObject.class.getDeclaredConstructor();

constructor.setAccessible(true);

OneObject newInstance = constructor.newInstance();

System.out.println(newInstance);

解决方案

public class OneObjectLaz {
	
	private static OneObjectLaz laz;
	
	private OneObjectLaz () {
		if (laz != null) throw new RuntimeException("对象必须保证单例!");
	}
	
	public static OneObjectLaz build () {
		synchronized (OneObjectLaz.class) {
			if (null == laz) laz = new OneObjectLaz();
		}
		
		return laz;
	}
	
}

防止序列化破解单例

public class OneObjectLaz {
	
	private static OneObjectLaz laz;
	
	private OneObjectLaz () {
		if (laz != null) throw new RuntimeException("对象必须保证单例!");
	}
	
	public static OneObjectLaz build () {
		synchronized (OneObjectLaz.class) {
			if (null == laz) laz = new OneObjectLaz();
		}
		
		return laz;
	}
	
	/**
	 * 防止单例, 反序列化破解
	 * 如果定义了: readResolve 方法在反序列时直接返回方法指定的对象, 不需要new了
	 */
	private Object readResolve() throws ObjectStreamException {
		return laz;
	}
	
}

要想真正的实现单利漏洞还是很多的所以jdk提供了新特性: enum

public enum One {

	ONE, TWO, THREE;
	
}
发布了49 篇原创文章 · 获赞 39 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42920045/article/details/88879355