xl_echo编辑整理


单例模式

单例模式(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();
});
}
}

代码地址: ​​https://coding.net/u/xlsorry/p/Demo/git​