xl_echo编辑整理,欢迎转载,转载请声明文章来源。欢迎添加echo微信(微信号:t2421499075)交流学习。
百战不败,依不自称常胜,百败不颓,依能奋力前行。——这才是真正的堪称强大!!
单例模式
单例模式(Singleton Pattern)是Java中最简单的设计模式之一,属于创建型,一般都用于保证唯一性的创建,这也是他最大的特点(保证全局只有唯一的一个实例),并且提供一个全局的访问点。
单例有以下几种形式
- 饿汉式
- 懒汉(存在线程安全问题)
- 注册登记式
- 枚举式
- 序列化(存在线程安全问题)
- 反序列化(存在线程安全问题)
创建单例一般要做一下几点:
- 私有化构造器
- 实例的创建
- 提供静态的对外访问的单例引用
饿汉式:不管用户是否使用,类加载的时候就会new一个对象出来,这样有效的避免了线程的安全问题。但是它也有对应的缺点,如果饿汉式使用较多,会对资源暂用较多。因为不管用不用该类,都创建了对象。
饿汉式代码示例如下:
public class HungryTest {
private HungryTest(){}
private static final HungryTest hungryTest = new HungryTest();
public static HungryTest getInstance(){
return hungryTest;
}
}
public class HungryTest2 {
private static final HungryTest2 HUNGRY_TEST_2;
private HungryTest2(){}
static {
HUNGRY_TEST_2 = new HungryTest2();
}
public static HungryTest2 getInstance(){
return HUNGRY_TEST_2;
}
}
懒汉式和饿汉式相反:默认类在加载的时候是不会进行对象创建的,一般是在用户使用的时候进行创建。如果使用比较多的情况下,可能会有并发的情况出现,这样就没法保证唯一对象。解决这个问题的办法有,直接在创建对象的方法上面添加synchronize,但是加上这个会出现新的问题那就是性能问题。
懒汉式代码示例如下:
//同步锁,但是性能略低
public class LazyOne {
private LazyOne(){}
private LazyOne lazyOne = null;
public synchronized LazyOne getInstatnce(){
if (lazyOne == null) {
lazyOne = new LazyOne();
}
return lazyOne;
}
}
注册式代码示例如下:
public class RegisterMap {
private RegisterMap() {}
private static Map<String, Object> map = new HashMap<>();
public static RegisterMap getInstance(String name) {
if (ObjectUtils.isEmpty(name)) {
name = RegisterMap.class.getName();
}
if (ObjectUtils.isEmpty(map.get(name))) {
map.put(name, new RegisterMap());
}
return (RegisterMap) map.get(name);
}
}
注册枚举式代码示例如下:
public enum EnumSingleton {
BLACK, WIRTH;
public void getInstance() {}
}
序列化代码示例如下:
public class SerializationSingleton implements Serializable {
private SerializationSingleton(){}
private static SerializationSingleton SERIALIZATION_SINGLETON = new SerializationSingleton();
public static SerializationSingleton getInstance(){
return SERIALIZATION_SINGLETON;
}
/**
* 序列化与反序列化的协议,能够保证单例线程安全。
*/
private Object readResolve(){
return SERIALIZATION_SINGLETON;
}
}
容器式单例代码示例如下
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 obj;
}
return ioc.get(className);
}
}
}
public class Person {}
public class ContainerSingletonTest {
public static void main(String[] args) {
IntStream.range(0, 10).forEach(it -> {
Thread thread = new Thread(() -> {
Object instance = ContainerSingleton.getBean("com.echo.demo.designPatterns.singletonDesignPatterns.container.Person");
System.out.println(Thread.currentThread().getName() + ":" + instance);
});
thread.start();
});
}
}