Java单例设计模式的实现
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修饰符修饰,查了一下主要是两个作用:
- 保证可见性。使用volatile定义的变量会保证对所有线程都是可见的;
- 禁止指令重排序优化。
更具体的理解可以参考这篇博客。
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单例设计模式的实现的更多相关文章
- Java——单例设计模式
设计模式:解决某一类问题最行之有效的方法.Java中23种设计模式:单例设计模式:解决一个类在内存中只存在一个对象. 想要保证对象唯一.1,为了避免其他程序过多建立该类对象.先禁止其他程序建立该类对象 ...
- 转:java单例设计模式
本文转自:http://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html 单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton ...
- Java单例设计模式和多例设计模式
单例设计模型 教学视频链接:https://edu.aliyun.com/course/1011 1,private不可以在类外部访问,但可以在内部访问 2,此时Singleton类内部的instan ...
- java 单例设计模式
1.饿汉单例设计模式: 步骤 : 1.定义一个私有的静态成员变量来引用对象(私有的静态对象),设置对象唯一. 2.私有化构造方法,防止new对象. 3.创建一个公开的静态方法,返回上面的 ...
- java单例设计模式总结及举例
* 设计模式:前人总结出来的经验,被后人直接拿来使用. * 单例设计模式:一个类只允许有一个对象,将这个对象作为一个全局的访问点,提供出去供大家使用. * 分析: * 1.用户只能有一个对象 * 2. ...
- 对Java单例设计模式中懒汉式类定义的讨论
全世界人民都知道单例设计模式中类的定义分为懒汉式和饿汉式两种,然而今天并不是要把它们做横向比较.实际上,不论饿汉式类的代码看起来有多么美轮美奂,在实际开发中它的效率总是不如懒汉式的.然而在笔试和面试中 ...
- Java单例设计模式(实现Java的一个类只有一个对象)
单例设计模式的定义:单例设计模式是一种软件设计模式,在它的核心包含一个称为单例类的核心类. 核心便是希望一个类只有一个对象. 如何实现类在内存中只有一个对象呢? 第一步:构造私有:第二步:本身提供一 ...
- java—单例设计模式
单例设计模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 1.构造方法私有化 2.声明一个本类对象 3.给外部提供一个静态方法获取对象实例 什么时候使用? 1.通过在工具类的设计中使用: ...
- Java 单例设计模式之 饿汉式和懒汉式
public class InstanceSampleTest { public static void main(String[] args) { /** 单例设计模式的 饿汉式和懒汉式 * 单例模 ...
随机推荐
- Luogu_1080_国王游戏
题目描述 恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这n位大臣排成一排,国王站在队伍的最前面.排好队 ...
- <USACO06FEB>奶牛零食Treats for the Cowsの思路
写不来dp的日常 ....就这样吧 #include<cstdio> #include<cstring> #include<iostream> #include&l ...
- python 自动发送邮件遇到的问题
在学习自动化测试高级应用,根据内容写关于自动发送邮件出现了几个问题以及解决办法: 问题1: 代码写好之后,运行的时候,出现如下报错: SMTPAuthenticationError: (550, '\ ...
- Linux设置redis密码登录
第一种:永久方式 redis设置密码访问 你的redis在真是环境中不可以谁想访问就可以访问,所以必须要设置密码 设置密码的流程如下: vim /etc/redis.conf 找到 #require ...
- PHP RabbitMQ 教程(三)
发布/订阅 我们在上一节创建了一个工作队列,并假定队列对应的任务传送给了某个客户端.在这一章节我们会做一些完全不一样的东西–我们会发送一条消息到多个消费者,也称之为"发布/订阅"模 ...
- Koa 学习
中间件引擎 1234567891011121314151617181920212223242526272829303132333435363738 const Koa = require('koa') ...
- Jprofile解析dump文件使用详解
1 Jprofile简介 官网 下载对应的系统版本即可 性能查看工具JProfiler,可用于查看java执行效率,查看线程状态,查看内存占用与内存对象,还可以分析dump日志. 2 功能简介 选择a ...
- 关于vue+element-ui项目的分页,返回默认显示第一页的问题解决
关于vue+element-ui项目的分页,返回默认显示第一页的问题解决 问题描述 当前页面如下: 然后点击页码跳到第3页,然后在第三页点击页面链接跳转到新的页面 然后在新页面点击返回按钮,返 ...
- Ⅱ:python入门
一.编程语言介绍 编程语言的分类: 机器语言 汇编语言 高级语言(编译型.解释型号) 总结: 执行效率:机器语言>汇编语言>高级语言(编译型>解释型) 开发效率:机器语言<汇编 ...
- JDBC大数据的采取
## JDBC的大类型数据的存取 ## # 基本概念: |-- 大文本类型数据和大二进制数据: 主要思想用于将大型的二进制数据(字节) 或是大型的文本数据(字符)从磁盘文件中读取 到数据库中,或是从数 ...