1. 单例设计模式的定义

单例设计模式确保类只有一个实例对象,类本身负责创建自己的对象并向整个系统提供这个实例。在访问这个对象的时候,访问者可以直接获取到这个唯一对象而不必由访问者进行实例化。

单例设计模式保证了全局对象的唯一性,在许多场景中都有应用。例如Windows中多个进程或线程同时操作一个文件的时候,所有的进程或线程对于同一个文件的处理必须通过唯一的实例来进行。

2. java单例设计模式的几种实现方式

单例设计的最大特点是类的构造函数是私有的,确保了只能由类本身创建对象,而访问者无法进行实例化。下面分别介绍五种java中常用的单例设计模式实现方式:

2.1 懒汉式

 public class Singleton{
private static Singleton instance; // 类的实例
private Singleton(){};   // 在获取类的实例的时候如果实例还未创建,则创建并返回
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}

是否Lazy初始化(即需要这个域的值的时候才进行初始化):是,在需要实例对象的时候才创建。

是否多线程安全:否

懒汉式是最基本的实现方式,但是线程不安全,如果多个线程访问类的对象,可能某个线程已经创建了但是由于没有同步,其他线程也会创建其他的Singleton对象。因此这种实现只能在单线程条件下工作。

2.2 懒汉式+synchronized同步锁

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

是否Lazy初始化:是

是否多线程安全:是

这种方式通过给getInstance()方法加上synchronized同步锁,使得当一个线程在获取对象时其他对象必须等待,等到当前线程释放锁之后其他线程才能获取对象,避免了创建多个对象的问题。但是这种方式由于其他线程必须等待,效率非常低。

2.3 饿汉式

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

是否Lazy初始化:否

是否多线程安全:是

饿汉式在类加载初始化的时候就创建好了自己的实例对象,除非系统重启类重新加载,否则类会一直维持这唯一一个对象,所以线程是安全的。

2.4 双重校验锁

 public 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;
}
}

是否Lazy初始化:是

是否多线程安全:是

双重校验锁是对上面第二种方法的一种优化,由于synchronized将整个getInstance()方法锁住导致效率降低,双重校验锁只对需要锁的部分加锁,提高了执行效率。

另一个值得注意的是,这种实现方式中对于instance变量使用了volatile修饰符修饰,查了一下主要是两个作用:

  1. 保证可见性。使用volatile定义的变量会保证对所有线程都是可见的;
  2. 禁止指令重排序优化。

更具体的理解可以参考这篇博客

2.5 静态内部类

 public class Singleton{
private Singleton(){}; private static class InnerSingleton{
private static final Singleton INSTANCE = new Singleton();
}
public static final Singleton getInstance(){
return InnerSingleton.INSTANCE;
}
}

是否Lazy初始化:是

是否多线程安全:是

静态内部类在实现时利用了classloader机制来保证初始化时只有一个线程,并且由于INSTANCE采用了final修饰,一旦被创建便不能修改,保证了对象的唯一性。另外,只有在显示调用getInstance()方法时才会装载InnerSingleton类,从而实例化对象。

参考资料

https://www.runoob.com/design-pattern/singleton-pattern.html

https://www.cnblogs.com/goodAndyxublog/p/11356402.html

Java单例设计模式的实现的更多相关文章

  1. Java——单例设计模式

    设计模式:解决某一类问题最行之有效的方法.Java中23种设计模式:单例设计模式:解决一个类在内存中只存在一个对象. 想要保证对象唯一.1,为了避免其他程序过多建立该类对象.先禁止其他程序建立该类对象 ...

  2. 转:java单例设计模式

    本文转自:http://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html 单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton ...

  3. Java单例设计模式和多例设计模式

    单例设计模型 教学视频链接:https://edu.aliyun.com/course/1011 1,private不可以在类外部访问,但可以在内部访问 2,此时Singleton类内部的instan ...

  4. java 单例设计模式

    1.饿汉单例设计模式:  步骤 :   1.定义一个私有的静态成员变量来引用对象(私有的静态对象),设置对象唯一.   2.私有化构造方法,防止new对象.   3.创建一个公开的静态方法,返回上面的 ...

  5. java单例设计模式总结及举例

    * 设计模式:前人总结出来的经验,被后人直接拿来使用. * 单例设计模式:一个类只允许有一个对象,将这个对象作为一个全局的访问点,提供出去供大家使用. * 分析: * 1.用户只能有一个对象 * 2. ...

  6. 对Java单例设计模式中懒汉式类定义的讨论

    全世界人民都知道单例设计模式中类的定义分为懒汉式和饿汉式两种,然而今天并不是要把它们做横向比较.实际上,不论饿汉式类的代码看起来有多么美轮美奂,在实际开发中它的效率总是不如懒汉式的.然而在笔试和面试中 ...

  7. Java单例设计模式(实现Java的一个类只有一个对象)

    单例设计模式的定义:单例设计模式是一种软件设计模式,在它的核心包含一个称为单例类的核心类. 核心便是希望一个类只有一个对象.  如何实现类在内存中只有一个对象呢? 第一步:构造私有:第二步:本身提供一 ...

  8. java—单例设计模式

    单例设计模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 1.构造方法私有化 2.声明一个本类对象 3.给外部提供一个静态方法获取对象实例 什么时候使用? 1.通过在工具类的设计中使用: ...

  9. Java 单例设计模式之 饿汉式和懒汉式

    public class InstanceSampleTest { public static void main(String[] args) { /** 单例设计模式的 饿汉式和懒汉式 * 单例模 ...

随机推荐

  1. DBCP + C3P0 连接池

    DBCP 配置参数如下: 参数 默认值 可选值 格式 说明 username       用户名 password       密码 url       数据库连接url driverClassNam ...

  2. Maven基本概念和操作

    最近在学Java,找来一个开源项目练手,它是用 Spring Boot 搭建的框架,于是去学 Spring Boot,然而 Spring Boot 需要有 Spring 框架和 Maven 的使用经验 ...

  3. Java Random函数

    Java中存在着两种Random函数: 1.java.lang.Math.Random: 调用这个Math.Random()函数能够返回带正号的double值,该值大于等于0.0且小于1.0,即取值范 ...

  4. Python---13面向对象编程

    一.类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法, ...

  5. JavaIO 流(1)IO流介绍

    IO流定义: 流的本质是一组单向有序,分起始和终止的数据传输过程.需要导入import java.io.* IO流分类: 按数据类型分为:字节流和字符流 字节流: 按字节进行读取(可以处理任意类型数据 ...

  6. curator配置及使用

    1.action.yml --- actions: 1: action: index_settings options: index_settings: index: routing.allocati ...

  7. 2.mac下 安装go-ethereum

    Contents 上代码 A.前期准备:http://m.2cto.com/kf/201612/573010.html (1)安装python2.7,mac在终端中直接使用以下命令:brew inst ...

  8. zabbix监控mysql数据库信息脚本

    ---恢复内容开始--- 在/usr/local/zabbix/etc/zabbix_agentd.conf增加 # 获取mysql性能指标 UserParameter=mysql.status[*] ...

  9. Vue1.0用法详解

    Vue.js 不支持 IE8 及其以下版本,因为 Vue.js 使用了 IE8 不能实现的 ECMAScript 5 特性. 开发环境部署 可参考使用 vue+webpack. 基本用法 1 2 3 ...

  10. Java程序监控---Metrics

    概念 Metrics是一个给JAVA服务的各项指标提供度量工具的包,在JAVA代码中嵌入Metrics代码,可以方便的对业务代码的各个指标进行监控 目前最为流行的 metrics 库是来自 Coda ...