Java创建单例模式(singleton)的几种实现方式


一、什么是单例模式?

单例模式是一个类只有一个实例对象。其构造函数是私有的,不能通过new方式创建实例对象。在整个程序的生命周期内都只存在一个单例类的实例对象,以静态方法或枚举返回唯一的实例化对象。

1. 优点

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

2. 缺点

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

3. 使用场景

①要求生产唯一序列号。
② WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
③ 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化

二、什么是线程安全和非线程安全?

1.线程安全

线程安全就是多线程访问时,采用了加锁机制,当一个线程访问某一个类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染的情况。

2.非线程安全

线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据,从而导致数据不一致,造成所得到的数据是脏数据

3.线程安全与不安全的本质区别

线程安全与不安全的本质区别在于对于共享资源的访问上的执行效果.安全线程在处理共享资源时效果具有原子性,即必须等到当前线程访问结束后别的线程才能继续访问.而非安全线程则任何时候都可以抢占cpu的使用权,导致的结果就是线程共享资源由于多线程争抢访问导致的数据错误问题.

三、单例模式的5种创建方式

1.饿汉式

//类加载时就创建一次实例,避免了多线程问题,但是还在使用就创建了对象,浪费内存
//线程安全
public class Singleton {
    private Singleton() {} 
    private static Singleton instance = new Singleton(); 
    public static Singleton getInstance() {
        return instance;
    }
}

2.懒汉式

//优点:需要的时候才进行创建
//缺点:线程不安全,多线程时会创建多个实例
public class Singleton {
    private Singleton() {}
    private static Singleton instance = null;
    public static Singleton getInstance() {
        if (null == instance) {
            instance = new Singleton();
        }
        return instance;
    }
}
//优点:线程安全,但是在多线程情况下还是有可能出现不安全的情况,
//threadA和threadB同时执行到if (null == instance)时就与可以出现创建多个实现
//缺点:添加了synchronized的函数比一般方法慢得多,若多次调用getInstance,则累积的性能损耗特别大。
public class Singleton {
    private Singleton() {}
    private static Singleton instance = null;
    public static synchronized Singleton getInstance() {
        if (null == instance) { 
           instance = new Singleton(); 
        }
        return instance;
    }
}

3.双重锁检测模式(Double Check Lock)

//多线程情况下还是可能出现创建多个实例情况,主要是因为jvm对命令进行重排序优化,而导致创建多个实例的情况。
public class Singleton {
    private Singleton() {}
    private static Singleton instance = null;
    public static Singleton getInstance() {
        if (null == instance) {
            synchronized (Singleton.class) {
                if (null == instance) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
//优点:线程安全,volatile关键词主要是保证多线程之间的可见性,保证线程在每次取值volatile变量都是最新值
//volatile关键字主要是禁止命令重排序的,但是volatile不是原子性的
public class Singleton {
 private static volatile Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (null == instance) {
            synchronized (Singleton.class) {
                if (null == instance) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

4.静态内部类模式

  public class Singleton {
    private Singleton() {}
    private static Singleton getInstance() {
        return SingletonHolder.instance;
    }
    private static class SingletonHolder {
    	//静态变量值会初始化一次
        private static Singleton instance = new Singleton();
    }
}

5.通过枚举实现单例模式

//优点:既能避免多线程同步问题,又能防止反序列化重新创建新的对象
public enum Singleton {
    INSTANCE;
    public void doSimthing(){
    }
}

参考文献:
Java单例模式的5种实现方法
单例模式
Java创建线程安全的单例singleton
volatile关键词
什么是指令重排序?为什么要重排序

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目 录 第1 章 模式的简史和形而上学........3 1.1 模式是什么...................................3 1.2 软件模式的简史...........................3 1.3 模式的起源...................................4 1.4 与道家思想的关系.......................5 1.5 软件的永恒之道...........................9 1.6 模式的要素...................................10 1.7 本书讲解模式的格式...................12 第2 章 统一建模语言UML 简介.....15 2.1 建造世界贸易中心.......................15 2.2 什么是UML.................................16 2.3 UML 包括什么.............................17 2.5 类图. 19 2.6 时序图...........................................27 2.7 状态图...........................................28 2.8 UML 及建模的工具.....................30 第3 章 软件的可维护性与可复用性35 3.1 软件系统的可维护性...................35 3.2 系统的可复用性...........................39 3.3 老子论“不武”...........................42 第4 章 “开-闭”原则(OCP).........45 4.1 什么是“开-闭”原则.................45 4.2 怎样做到“开-闭”原则.............45 4.3 与其他设计原则的关系...............47 4.4 策略模式对“开–闭”原则的支持 ........49 4.5 在其他设计模式中的体现...........50 4.6 一个重构做法的讨论...................54 第5 章 专题:Java 语言的接口........59 5.1 什么是接口...................................59 5.2 为什么使用接口...........................60 5.3 Java 接口常见的用法...................63 第6 章 专题:抽象类........................69 6.1 什么是抽象类...............................69 6.2 抽象类是用来继承.......................70 6.3 基于抽象类的模式和原则...........72 6.4 什么时候才应当使用继承复用...73 第7 章 里氏代换原则(LSP) .........79 7.1 美猴王的智慧...............................79 7.2 什么是里氏代换原则...................80 7.3 里氏代换原则在设计模式中的体现 ....... 82 7.4 墨子论“取譬”...........................83 7.5 从代码重构的角度理解...............84 第8 章 依赖倒转原则(DIP)..........95 8.1 为何而“倒转”...........................95 8.2 复用与可维护性的“倒转”.......96 8.3 依赖倒转原则...............................96 8.4 怎样做到依赖倒转原则...............99 8.5 Java 对抽象类型的支持...............101 8.6 一个例子:账号、账号的种类和账号 的状态...... 103 8.7 墨子论“取周”...........................106 8.8 依赖倒转原则的长处和短处.......107 第9 章 接口隔离原则(ISP) ..........109 9.1 什么是接口隔离原则...................109 9.2 一个角色隔离原则的例子...........110 9.3 定制服务的例子...........................112 第10 章 合成/聚合复用原则(CARP) ....... 115 10.1 合成和聚合的区别.....................115 10.2 复用的基本种类.........................115 10.3 从代码重构的角度理解.............117 第11 章 迪米特法则(LoD)...........121 11.1 迪米特法则的各种表述.............121 11.2 狭义的迪米特法则.....................121 《Java 与模式》作者阎宏博士 电子工业出版社出版 11.3 迪米特法则与设计模式.............126 11.4 广义的迪米特法则.....................128 11.5 广义迪米特法则在类的设计上的体 现....129 11.6 广义迪米特法则在代码层次上的实 现....133 11.7 老子论“圣人之治”.................133 第12 章 简单工厂(Simple Factory)模式 ........139 12.1 工厂模式的几种形态.................139 12.2 简单工厂模式的引进.................139 12.3 简单工厂模式的结构.................146 12.4 简单工厂模式的实现.................148 12.5 简单工厂模式与其他模式的关系 ........153 12.6 模式的优点和缺点.....................155 12.7 简单工厂模式在Java 中的应用156 12.8 女娲抟土造人.............................160 第13 章 工厂方法(Factory Method)模式 ........165 13.1 引言.............................................165 13.2 工厂方法模式的结构.................167 13.3 工厂方法模式在农场系统中的实现 ........172 13.4 关于工厂方法模式的实现.........177 13.5 Java 语言中工厂方法模式的例子 ........179 13.6 工厂方法模式与其他模式的关系 ........182 13.7 女娲举绳造人.............................185 13.8 其他的例子.................................185 第14 章 抽象工厂(Abstract Factory)模 式....193 14.1 引言.............................................193 14.2 问题.............................................195 14.3 抽象工厂模式的结构.................198 14.4 在什么情形下应当使用抽象工厂模 式....204 14.5 抽象工厂模式在农场系统中的实现 ....... 205 14.6 抽象工厂模式的另一个例子.....211 14.7 “开-闭”原则..............................212 14.8 关于模式的实现.........................213 14.9 女娲造万物的故事.....................214 第15 章 单例(Singleton)模式.......221 15.1 引言.............................................221 15.2 单例模式的结构.........................222 15.3 在什么情况下使用单例模式.....228 15.4 单例类的状态.............................229 15.5 一个实用的例子:属性管理器.230 15.6 Java 语言中的单例模式.............235 15.7 专题:不完全的单例类.............239 15.8 相关模式.....................................240 15.9 附录:双重检查成例的研究.....243 15.10 给读者的一点建议...................247 第16 章 专题:单例模式与MX 记录 ....... 249 16.1 问题与解决方案.........................249 16.2 目录服务与MX 记录................251 16.3 JNDI 架构介绍...........................252 16.4 如何使用JNDI 编程..................253 16.5 系统设计.....................................255 16.6 讨论.............................................261 第17 章 专题:多例(Multiton)模式与多 语言支持.. 267 17.1 引言.............................................267 17.2 多例模式.....................................269 17.3 多语言项目的设计.....................272 第18 章 专题:序列键生成器与单例及多 例模式...... 283 18.1 问题.............................................283 18.2 将单例模式应用到系统设计中.285 18.3 将多例模式应用到系统设计中.297 18.4 讨论.............................................300 第19 章 建造(Builder)模式..........301 19.1 引言.............................................301

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值