设计模式-单例模式及多种实现

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();
        });
    }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xlecho

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值