单例模式

简介: 什么是单例模式?在一个项目中,单例模式确保某一个类只能有一个实例,这个类称为单例类。怎样确保某个类只能有一个实例,通常调用方法有两种方式: 创建类的一个对象,即new出一个对象,用该对象去调用类中方法; 使用类名直接调用类中方法,格式“类名.方法名()”想要类只有一个实例,必不能随意通过new出对象,禁止new对象就只能私有化构造方法,采用“类名.方法名()”这种方式获取方法。

什么是单例模式?在一个项目中,单例模式确保某一个类只能有一个实例,这个类称为单例类。
怎样确保某个类只能有一个实例,通常调用方法有两种方式:

  1. 创建类的一个对象,即new出一个对象,用该对象去调用类中方法;
  2. 使用类名直接调用类中方法,格式“类名.方法名()”
    想要类只有一个实例,必不能随意通过new出对象,禁止new对象就只能私有化构造方法,采用“类名.方法名()”这种方式获取方法。通过类名对用方法,此方法是属于类的方法,由于类的加载顺序限定,此方法必须是静态(static)的,且方法里的属性也必须是静态的。

单例核心三要素:

  1. 构造方法私有化
  2. 提供静态(static)的得到类对象的方法
  3. 类属性设为static

单例模式根据对象的创建时间不同,有分为EagerSingleton和LazySingleton。
EagerSingleton方法:

public class EagerSingleton {
    /** 静态方法访问静态成员变量*/
    private static EagerSingleton instance = new EagerSingleton();
    /** 私有构造方法,防止被实例化 */
    private EagerSingleton(){
    }
    /** 提供调用的方法 */
    public static EagerSingleton getInstance(){
        return instance;
    }
}

EagerSingleton方法缺点是该类加载的时候就会直接new 一个静态对象,当系统中单例类较多时,会使得启动速度变慢。
LazySingleton方法:

public class LazySingleton {
    //非线程安全
    private static LazySingleton instance = null;
    private LazySingleton(){
    }
    public static LazySingleton getInstance1(){
        if(instance == null){
            instance = new LazySingleton();
        }
        return instance;
    }
}

提供双重锁写法,保证线程安全:

public class DoubleCheckLock {

    private volatile static DoubleCheckLock instance = null;

    private DoubleCheckLock(){
    }

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

“双重检查加锁”机制是当每次执行getInstance方法时先不同步,先检查instance是否存在,如果不存在才进行加锁,这是第一重检查;进入同步块synchronized 方法后,再次检查实例是否存在,如果不存在就创建实例instance,这是第二重检查。DoubleCheckLock 机制使用关键字volatile,被volatile修饰的变量值不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的操作该变量。

参考:
1.https://www.cnblogs.com/java-my-life/archive/2012/03/31/2425631.html

目录
相关文章
|
开发框架 IDE .NET
.NET 6 之 ABP vNext 初体验
本文将介绍在 .net6 平台的 asp.net core webapi 框架中,如何使用 abp vnext 框架进行模块化开发,重在思想理解。
1393 1
.NET 6 之 ABP vNext 初体验
|
Unix Linux 数据库
Linux 下samba的使用简介
Linux 下samba的使用简介
122 0
|
Shell Linux Perl
Linux - Shell 脚本中获取本机 ip 地址方法
Linux - Shell 脚本中获取本机 ip 地址方法
1632 0
Linux - Shell 脚本中获取本机 ip 地址方法
|
Perl 容器 Kubernetes
K8S中手动扩容云盘数据卷
K8S中手动扩容云盘数据卷 介绍: 云盘数据卷扩容包括以下几个部分: 云盘物理空间扩容,需要在云盘控制台操作;文件系统扩容,需要挂载云盘到一个物理节点手动操作;PV、PVC Size更新,需要更新StorageClass、PVC; 注意:扩容云盘前需要为云盘打快照,以预防升级失败导致数据丢失; 云盘目前无法做到在线扩容,需要重启应用才可以实现,可以通过两种方法实现云盘扩容。
8196 0
|
JavaScript 前端开发 测试技术
|
PHP 数据库
ecshop 工作流程加载配置介绍
  ecshop 工作流程加载配置介绍 分类: ecshop2014-09-14 09:36 729人阅读 评论(2) 收藏 举报 模板引擎工作流 这里简单介绍下echsop工作流程:   首先,你会发现一般的echsop的php文件都会引入init.php这个文件一般在includes/init.php。
1263 0
|
JavaScript 前端开发
十个非常有创意的验证码设计
  验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机和人的公共全自动程序,可以防止恶意破解密码、刷票、论坛灌水等等。
1082 0