单例模式

单例模式的定义

定义:Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类
只有一个实例,而且自行实例化并向整个系统提供这个实例。)

单例模式的通用代码:

public class Singleton {//饥汉式
    private static final Singleton singleton = new Singleton();
    //限制产生多个对象
    private Singleton() {
    }
    //通过该方法获得实例对象
    public static Singleton getSingleton() {
        return singleton;
    }
    //类中的其他方法,尽量static
    public static void doSomething() {
        
    }
}

单例模式的应用

单例模式的优点

  • 减少内存开支
  • 减少系统的性能开销
  • 避免对资源的多重占用
  • 设置全局访问点,优化和共享资源访问

单例模式的缺点

  • 单例模式没有接口,扩展困难
  • 单例模式对测试不利
  • 单例模式与单一职责冲突

单例模式的使用场景

  • 要求生成唯一序列号的环境
  • 需要一个共享的访问点或共享数据(Web页面的计数器)
  • 创建一个对象消耗的资源过多(访问IO和数据库)
  • 需要定义大量静态常量和静态方法(如工具类)的环境(也可以直接声明为static方法)

单例模式的注意事项

高并发情况下,单例模式的线程同步问题
上一段代码不会出现产生多个实例的情况,但是,下面这个就可能了

public class Singleton {//懒汉式(synchronized关键字解决线程同步问题)
    private static Singleton singleton = null;
    //限制产生多个对象
    private Singleton() {
    }
    //通过该方法获得实例对象
    public synchronized static Singleton getSingleton() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
    //类中的其他方法,尽量static
    public static void doSomething() {

    }
}

单例模式的扩展

产生固定数量对象的模式------有上限的多例模式,他是单例模式的扩展,采用有上限的多例模式,我们可以在设计是决定在内存中有多少个实例,方便系统进行扩展,修正单例可能存在的性能问题,提供系统的响应速度。(读取文件,我们可以在系统启动时完成初始化工作,在内存中启动固定数量的reader实例,在需要读取文件时就可以快速响应

public class Emperors {
    private static int maxNumOfEmperor = 2;
    private static ArrayList<String> nameList = new ArrayList<>();
    private static ArrayList<Emperors> emperorList = new ArrayList<>();
    private static int countNumOfEmperor = 0;
    static {
        for (int i = 0; i <maxNumOfEmperor ; i++) {
            emperorList.add(new Emperors("黄" + i + "帝"));
        }
    }
    private Emperors() {
    }

    private Emperors(String name) {
        nameList.add(name);
    }
    public static Emperors getInstance() {
        Random random = new Random();
        countNumOfEmperor = random.nextInt(maxNumOfEmperor);
        return emperorList.get(countNumOfEmperor);
    }

    public void say() {
        System.out.println(nameList.get(countNumOfEmperor));
    }
}
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值