栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

单例模式及其实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

单例模式及其实现

一、简介

作用:保证一个类仅有一个实例,并提供一个访问它的全局访问点

主要解决:一个全局使用的对象频繁地创建与销毁

何时使用:当需要控制实例数目,节省系统资源的时候

如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建

关键代码:构造函数是私有的

优点:

  • 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)
  • 2、避免对资源的多重占用(比如写文件操作)

缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化

使用场景:

  • 1、要求生产唯一序列号
  • 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来
  • 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等
二、实现 1、饿汉式

饿汉式的意思就是程序在加载的时候就创建单例

class Singleton {
    private Singleton() {}
    public static Singleton instance = new Singleton();
}

这就是一个饿汉式的简单实现。private保证构造函数不能在别的类中调用,static保证类加载时就会创建对象且线程安全。可直接通过Singleton.instance访问唯一实例

但是,更加推荐使用枚举类

enum Singleton {
    instance;
}

一行,就一行。不仅保证了唯一实例,而且保证了反序列化后的实例唯一性(这里的深层原因等到以后有时间再深究)

2、懒汉式

懒汉式就是说第一次使用这个实例时再创建实例,之后再使用就可以直接调用

优点:减少内存开销

缺点:实现比饿汉式更加复杂,需要考虑线程安全

既然要保证线程安全,最简单的方法就是加synchronized锁

class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        return instance != null ? instance : new Singleton();
    }
}

但是缺点就是锁开销太大,所以有一种基于双重检查的懒汉式实现

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

注意到instance使用了volatile关键字,在获取instance时,不是一定要加synchronized锁,而是先检查是否已经实例化,如果没有,再加锁,再检查是否需要实例化,这就是双重检查

因为只有第一次实例化时需要加锁,所以比直接用锁效率更高

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/281152.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号