Java设计模式:单例模式

2020.08.01 07:08:44
2
阅读约2分钟

单例模式 #

饿汉单例模式 #

img 饿汉单例模式在类加载的时候就立即初始化,并且创建单例对象。它绝对线程安全,在线程还没出现以前就实例化了,不可能存在访问安全问题。
优点:没有加任何锁、执行效率高,用户体验比懒汉模式更好。
缺点:类加载的时候初始化,不管使用与否都会占用内存。
代码示例:

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

    private HungrySingleton(){}
    public  static  HungrySingleton  getInstance(){
       return  hungrySingleton;
    }
}

还有另外一种写法,放在静态代码块中

public class HungrySingleton {
    private static final HungrySingleton hungrySingleton;

    static {
        hungrySingleton = new HungrySingleton();
    }

    private HungrySingleton(){}
    public  static  HungrySingleton  getInstance(){
        return  hungrySingleton;
    }
}

鱼与熊掌兼得的写法 #

public class LazyInnerClassSingleton {

    private LazyInnerClassSingleton(){}
    public  static  final  LazyInnerClassSingleton  getInstance(){
        return  LazyHolder.LAZY;
    }

    private static class LazyHolder{
        private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();
    }
}

为了防止单例模式被破坏,我们可以加一些限制

public class LazyInnerClassSingleton {

    private LazyInnerClassSingleton(){
        if(LazyHolder.LAZY!=null){
            throw new RuntimeException("不允许创建多个实例");
        }
    }
    
    public  static  final  LazyInnerClassSingleton  getInstance(){
        return  LazyHolder.LAZY;
    }

    private static class LazyHolder{
        private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();
    }
}

自此,自认为史上最牛的单例模式的实现方式便大功告成了。

容器式单例模式 #

容器式单例模式适用于实例非常多的情况,便于管理,但它是非线程安全的。创建ContainerSingleton类

public class ContainerSingleton {
    private ContainerSingleton(){}
    private static Map<String,Object> ioc =new ConcurrentHashMap<String,Object>();

    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;
            }else{
                return ioc.get(className);
            }
        }
    }
}

现在我们来看看spring中的容器式单例模式的实现代码。

public abstarct class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implemments AutowireCapableBeanFactory{
    private final Map<Stringm,BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>(16);
}

线程单例实现threadLocal #

ThreadLocal不能保证其创建的对象是全局唯一的,但是能保证在单个线程中是唯一的。天生是线程安全的。

public class ThreadLocalSingleton {
    private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance = new ThreadLocal<ThreadLocalSingleton>(){
        @Override
        protected ThreadLocalSingleton initialValue() {
            return new ThreadLocalSingleton();
        }
    };
    private  ThreadLocalSingleton(){}

    public static  ThreadLocalSingleton getInstance(){
        return threadLocalInstance.get();
    }

}

写一下测试代码

class  main {
     public static void main(String[] args) throws InterruptedException {
         System.out.println(ThreadLocalSingleton.getInstance());
         System.out.println(ThreadLocalSingleton.getInstance());
         System.out.println(ThreadLocalSingleton.getInstance());
         System.out.println(ThreadLocalSingleton.getInstance());
         System.out.println(ThreadLocalSingleton.getInstance());
         Thread t1 = new Thread(() -> {
             ThreadLocalSingleton instance = ThreadLocalSingleton.getInstance();
             System.out.println(instance);
         });
         Thread t2 = new Thread(()->{
             ThreadLocalSingleton instance = ThreadLocalSingleton.getInstance();
             System.out.println(instance);
         });
         t1.start();
         t2.start();
//         Thread.sleep(10000);
         System.out.println("end");

     }
}
阅读:2 . 字数:337 发布于 13 天前
本作品系 原创 , 采用 《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
推荐阅读
资源
  • 创意设计
  • 书栈网
  • 帮助中心
  • 声望与权限
  • 服务中心
  • 合作
  • 关于我
  • 广告投放
  • 职位发布
  • 联系我们
  • 关注
  • 技术日志
  • 运营日志
  • ❤ 609 天
  • 条款
  • 服务条款
  • 隐私政策
  • 下载 App
  • Copyright © 2018-2020 Siques