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. Elegy written in a country church-yard

    分享一首好诗:托马斯·格雷的<墓地哀歌>. "ELEGY WRITTEN IN A COUNTRY CHURCH-YARD" The curfew tolls the ...

  2. ZooKeeper源码阅读——client(二)

    原创技术文章,转载请注明:转自http://newliferen.github.io/ 如何连接ZooKeeper集群   要想了解ZooKeeper客户端实现原理,首先需要关注一下客户端的使用方式, ...

  3. mac下配置开发环境

    常用命令 显示隐藏文件 1 defaults write com.apple.finder AppleShowAllFiles -boolean true ; killall Finder 关闭隐藏文 ...

  4. 「知乎」对中国用户而言,Pure Android 是否比 MIUI 或 Flyme 体验更好? - Donnie的博客

    这篇文章转载自我在知乎上的回答 哎呀-不要站队嘛.其实这是一个很有意思的题目,让我们一点点来看 哦对,谢妖-.本人是Nexus 5用户,系统当然是Pure Android KitKat啦(臭谷粉!点D ...

  5. 深度学习遥感影像(哨兵2A/B)超分辨率

    这段时间,用到了哨兵影像,遇到了一个问题,就是哨兵影像,它的RGB/NIR波段是10米分辨率的,但是其他波段是20米和60米的,这就需要pansharpening了,所以我们需要设计一种算法来进行解决 ...

  6. python安装pip (windows64)

    1.前提条件是先安装了easy_install(easy_install安装教程http://www.cnblogs.com/IT-Crowd/articles/6528469.html) 2.在ea ...

  7. 7-34 jmu-python-是否偶数 (10 分)

    输入一个整数,判断是否偶数 输入样例: 7 输出样例: 7不是偶数 输入样例: 8 输出样例: 8是偶数 a = int(input()) if (a % 2 == 0): print('%d是偶数' ...

  8. centos 7上openJdk 安装

    为什么不安装Oracle版本 oracle jdk 现在下载太恶心了会被登陆拦截.于是就安装openjdk. 步骤 下载 yum -y install java-1.8.0-openjdk java- ...

  9. 处理 Vue 单页面 SEO 的另一种思路

    vue-meta-info 官方地址: https://github.com/monkeyWang... (设置vue 单页面meta info信息,如果需要单页面SEO,可以和 prerender- ...

  10. 一步步打造自己的纯CSS单标签图标库

    图标作为网页设计中的一部分,其在凸显网页重要元素特性,视觉交互.引导以及网页装饰等充当的角色作用举足轻重.由于图标普遍具有尺寸小的特点,在项目实践时不宜将每个图标作为单个图片元素进行加载,这会增加Ht ...