博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之——单例模式
阅读量:4511 次
发布时间:2019-06-08

本文共 2897 字,大约阅读时间需要 9 分钟。

1 概念

  一个类有且仅有一个实例,并且自行实例化向整个系统提供。

2 适用场景

  一些资源管理器构件必须只有一个实例。

3 实现以及优缺点

  单例优点:提供了对唯一实例的受控访问,由于在系统内存中只存在一个对象,因此可以节约系统资源。

  单例缺点:在一定程度上违背了单一职责原则。

3.1 饿汉模式

  优点:在类被初始化的时候就在内存中创建了对象,故线程安全。

  缺点:空间换时间

package Singleton;/** * 饿汉模式 */public class SingletonOne {    private SingletonOne instance = new SingletonOne();    private SingletonOne() {    }    private SingletonOne getInstance() {        return instance;    }}

  

3.2 懒汉模式

  缺点:不用就不实例化,在方法被调用后才创建对象,在多线程下存在风险。为线程非安全方式。

package Singleton;/** * 懒汉模式 */public class SingletonTwo {    private SingletonTwo instance;    private SingletonTwo() {    }    private SingletonTwo getInstance() {        if (null == instance) {            return new SingletonTwo();        }        return instance;    }}

  

3.3 线程安全的懒汉式

  优点:线程安全。

  缺点:由于每次调用都需要进行同步,而且大部分情况下实例是已经创建成功了,造成了不必要的同步开销,不建议用这种方式。

package Singleton;/** * 线程安全的懒汉式 */public class SingletonThree {    private SingletonThree instance;    private SingletonThree() {    }    private synchronized SingletonThree getInstance() {        if (null == instance) {            return new SingletonThree();        }        return instance;    }}

  

3.4 双重检查模式的懒汉式DCL

  该方法线程安全,声明为volatile实例对象,确保了多线程时的可见性,同时同步方法移步到代码块中,只有在该对象没有被实例化的时候才调用同步方法,节省了一部分开销。

  特点:其一为用volatile修饰类实例对象;其二同步代码块。

package Singleton;public class SingletonDcl {
  //volatile修饰的值,在线程独有的工作内存中,线程直接和主内存交互,如果修改,则主内存立即可见。 private volatile SingletonDcl instance = null;   //私有构造器,使外部调用初始化时只能通过调用getInstance这个静态方法来获得实例。 private SingletonDcl() { } private SingletonDcl getInstance() { if (null == instance) //首先进行非空判断。      { synchronized (SingletonDcl.class)//对整个类进行加锁,限制当前对象只能被一个线程访问        { return new SingletonDcl(); } } return instance; }}

 

3.5 静态内部类单例模式

  特点:利用静态类只会加载一次的机制,由于在调用 SingletonHolder.instance 的时候,才会对单例进行初始化,故节省了内存开销。

package Singleton;/** * 线程安全静态内部类 */public class SingletonStatic {    private SingletonStatic() {    }    public static class SingletonHolder {        private static SingletonStatic instance = new SingletonStatic();    }    private SingletonStatic getInstance() {        return SingletonHolder.instance;    }}

  

4 举例实践

4.1 JDK Runtime,饿汉模式

  java是单进程,由于一个java程序启动一个jvm进程,一个jvm进程对应一个Runtime实例,使应用程序能够与其运行的环境相连接。

public class Runtime {    private static Runtime currentRuntime = new Runtime();    /**     * Returns the runtime object associated with the current Java application.     * Most of the methods of class Runtime are instance     * methods and must be invoked with respect to the current runtime object.     *     * @return  the Runtime object associated with the current     *          Java application.     */    public static Runtime getRuntime() {        return currentRuntime;    }}

  

4.2 Logger

 

5.扩展

问:为什有私有构造器

答:防止外部构造者直接实例化对象。

问:对象在实例化过程中的操作实例化空间如何计算

答:首先了解存储区域,请参考

 

转载于:https://www.cnblogs.com/guobm/p/10053493.html

你可能感兴趣的文章
使用Python的requests模块编写请求脚本
查看>>
ERP 高级查询(Advanced Query)设计与实现 SQL语句解析成LLBL Gen ORM代码
查看>>
gfs下载文件较大,可以分区域分变量下载
查看>>
用 Mahout 和 Elasticsearch 实现推荐系统
查看>>
预装windows7 C盘只能分出一半空间的解决办法
查看>>
MySql绿色库(无需安装) 可以由打包工具直接打包
查看>>
理解HTTP幂等性,分布式事物
查看>>
luogu4219 and bzoj4530 大融合
查看>>
python安装setup.py问题
查看>>
【算法03】n个骰子的总和
查看>>
(剑指Offer)面试题3:二维数组中的查找
查看>>
layer的简单使用
查看>>
命名空间
查看>>
JS禁止右键,禁止Ctrl键,禁止选中文字
查看>>
XtraGrid判断列有没有显示
查看>>
MySQL系列--3.数据类型和连接查询
查看>>
servlet的url-pattern匹配规则详细描述
查看>>
jquery 进度条
查看>>
《BI那点儿事》数据流转换——查找转换
查看>>
二叉树中和为某一值的路径
查看>>