前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >单例模式

单例模式

原创
作者头像
老兵程序员
修改2021-07-19 11:31:13
3440
修改2021-07-19 11:31:13
举报

应用场景

封装一些常用的工具类,保证整个应用常用的数据统一
保存一些共享数据在内存中,其他类随时可以读取。
创建对象耗时或者耗费资源过多,但又需要频繁用到;
需要频繁的进行创建和销毁的对象;

注意:如果写成单例模式就不要用spring注入了,spring注入默认单例,两者重复

7种方式

饿汉式

线程安全

public class Singleton {

    private static final Singleton instance = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

线程安全,类加载的时候实例化,意思就是在初始化instance的时候就new了,所以导致资源浪费(吹毛求疵的说)

懒汉式-线程不安全

线程不安全

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
首次我调用getInstance,那么就会进行类加载,这时候instance引用没被初始化。
然后进行判断空后,给instance引用初始化一个对象。

下次调用getInstance因为是不是空,直接返回。

疑问:我调用getInstance后,都会返回一个对象。饿汉式只是说初始化的时候就new了对象,而我这做了判断再new,实质上都把对象new了。那么懒汉式节省资源体现在哪?
    
    体现在你调用类的其它方法的时候,它不会new(实例化)对象!

上代码!

懒汉式-同步方法

线程安全,同步方法

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
线程安全,但效率低下!

懒汉式,双重检测

线程安全,同步代码块

public class Singleton {

    private static volatile Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

兼顾效率和线程安全,可以用。但是性能不高

静态内部类(推荐)

线程安全

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {

        private static final Singleton INSTANCE = new Singleton();
    }

}
业务这种够用,线程安全+懒加载

枚举

线程安全

public enum Singleton {
    INSTANCE;
}

知道就行,线程安全,防反射,防反序列化。其它方式不防!

枚举懒加载

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class ThreadPoolUtil {
    private enum innerEnum {

        INSTANCE;
        private final ThreadPoolExecutor executor;
        private final ThreadPoolUtil threadPoolUtil;

        innerEnum() {

            ThreadPoolExecutor.CallerRunsPolicy policy = new ThreadPoolExecutor.CallerRunsPolicy();

            executor = new ThreadPoolExecutor(0,
                    Integer.MAX_VALUE,
                    60L, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>(),
                    policy
            );
            threadPoolUtil = new ThreadPoolUtil();
        }

        private ThreadPoolExecutor getThreadPool() {
            return executor;
        }

        private ThreadPoolUtil threadPoolUtil() {
            return threadPoolUtil;
        }
    }


    public static ThreadPoolUtil getInstance() {
        return innerEnum.INSTANCE.threadPoolUtil();
    }


    public ThreadPoolExecutor getThreadPool() {
        return innerEnum.INSTANCE.getThreadPool();
    }
}

这部分拿不准,先放在这里。所以说枚举到底是不是懒加载,是的话又例子论证吗?网上说法不一,搞不懂

最后再宣传一波,我的个人主页:个人主页,在这里你将收获我的成长知识库,不限于后端、前端、生活等知识库哟~

期待和老兵合作?想知道我能为你做什么?点击这里吧!我能做什么?


转载合作联系老兵,私自盗用必究!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 饿汉式
  • 懒汉式-线程不安全
  • 懒汉式-同步方法
  • 懒汉式,双重检测
  • 静态内部类(推荐)
  • 枚举
  • 枚举懒加载
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档