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) { /** 单例设计模式的 饿汉式和懒汉式 * 单例模 ...
随机推荐
- 高效能Windows人士的N个习惯之一:启动篇
接触电脑十多年,经历了各种折腾阶段,这几年开始沉静下来,不再追求花哨的界面与应用,只注重工作的效率,逐渐养成了一套自己的操作习惯,感觉不错,特撰文分享.标题借用了一下<高效能人士的七个习惯> ...
- 二十一世纪计算 | John Hopcroft:AI革命
编者按:信息革命的浪潮浩浩汤汤,越来越多的人将注意力转向人工智能,想探索它对人类生产生活所产生的可能影响.人工智能的下一步发展将主要来自深度学习,在这个领域中,更多令人兴奋的话题在等待我们探讨:神经网 ...
- array-2
数组的基本操作 JS随机操作数组元素 Math.random() 结果为0-1间的一个随机数[0,1) Math.round(num) 参数num为一个数值,函数结果为num四舍五入的整数 Math. ...
- C++扬帆远航——9(小学生算数程序)
/* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:studentjishu.cpp * 作者:常轩 * 微信公众号 ...
- LeetCode【面试题 16.17. 连续数列】
------------恢复内容开始------------ 题目描述 给定一个整数数组(有正数有负数),找出总和最大的连续数列,并返回总和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5 ...
- DotNet Core 使用 StackExchange.Redis 简单封装和实现分布式锁
前言 公司的项目以前一直使用 CSRedis 这个类库来操作 Redis,最近增加了一些新功能,会存储一些比较大的数据,内测的时候发现其中有两台服务器会莫名的报错 Unexpected respons ...
- Burpsuite专题学习指南
点击蓝色字体即可 开启你的Burp学习之旅BurpSuite系列(一)----Proxy模块(代理模块) BurpSuite系列(二)----Target模块(目标模块) BurpSuite系列(三) ...
- Java面试必问之Hashmap底层实现原理(JDK1.8)
1. 前言 上一篇从源码方面了解了JDK1.7中Hashmap的实现原理,可以看到其源码相对还是比较简单的.本篇笔者和大家一起学习下JDK1.8下Hashmap的实现.JDK1.8中对Hashmap做 ...
- 一块小饼干(Cookie)的故事-下篇
上篇介绍了注册的基本流程,下篇简单的讲讲登录的流程以及Cookie的出现 实现登录的小功能 当你在浏览器的输入框里输入localhost:8080/sign_in的时候,会发起GET请求,去访问sig ...
- Java easyui 下拉框默认选中第一个
html代码: <tr> <td> <div style="margin-bottom:5px">计价方式: <%--下拉框默认选中第 ...