Java基础系列-单例的7种写法
原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755322.html
一、概述
Java中单例有7种写法,这个是在面试中经常被问到的内容,而且有时候还要求手写单例实现方式。所以我们有必要认真的了解一下这七种写法。
二、七种实现
2.1 懒汉式——线程不安全
public class SingletonOne {
public static SingletonOne singleton;
private SingletonOne() {}
public static SingletonOne getSingleton() {
if (singleton == null)
return new SingletonOne();
return singleton;
}
}
懒汉式实现了懒加载,但是线程不安全,基本不会使用。
2.2 懒汉式——线程安全
public class SingletonTwo {
public static SingletonTwo singleton;
private SingletonTwo() {}
public static synchronized SingletonTwo getSingleton() {
if (singleton == null)
return new SingletonTwo();
return singleton;
}
}
在第一种的基础上加了个synchronized,保证线程安全,同时实现了懒加载,只是效率不高。
2.3 饿汉式
public class SingletonThree {
public static SingletonThree singleton = new SingletonThree();
private SingletonThree () { }
public static SingletonThree getSingleton() {
return singleton;
}
}
由于实例优先提供,不存在线程安全问题,但是没有实现懒加载。
2.4 饿汉式——变种
public class SingletonFour {
public static SingletonFour singleton;
static {
singleton = new SingletonFour();
}
private SingletonFour () { }
public static SingletonFour getSingleton() {
return singleton;
}
}
其实和之前的一样,仅仅是将单例的创建挪到了静态块。
2.5 静态内部类式
public class SingletonFive {
private static class SingletonHolder {
private static SingletonFive singleton = new SingletonFive();
}
private SingletonFive () {}
public static final SingletonFive getSingleton(){
return SingletonHolder.singleton;
}
}
静态内部类保证了懒加载,单例实例优先提供又保证了线程安全性,较实用。
2.6 枚举式
public enum SingletonSix {
SINGLETON;
}
枚举的天然特性保证了单例,天然的私有构造器,天然的线程安全性,未被大规模使用的原因是枚举出现的有点晚。
2.7 双重校验锁式
public class SingletonSeven {
private static volatile SingletonSeven singleton;
private SingletonSeven() {}
public static SingletonSeven getSingleton(){
if (singleton == null) {
synchronized (SingletonSeven.class) {
if (singleton == null)
return new SingletonSeven();
}
}
return singleton;
}
}
注意:
- volatile的使用,为了防止暴露一个未初始化的不完整单例实例;
- 双重判空校验,第一个判断避免了频繁的加锁,第二个判断可以拦住多余的创建实例的线程;
- 加锁,保证了线程安全(只有一个实例)
这种实现方式是经常出现在面试题中的,而且经常会要求手写。
三、总结
上面罗列的7种设计模式中第1种线程不安全,可以排除在外,第3、4种其实是一种,这样下来其实可以简化为5种方式:懒汉、饿汉、静态内部类、枚举、双重校验锁。
Java基础系列-单例的7种写法的更多相关文章
- 转载:java基础之单例
转载:https://blog.csdn.net/goodlixueyong/article/details/51935526 https://www.cnblogs.com/cielosun/p/6 ...
- Java并发编程中的设计模式解析(二)一个单例的七种写法
Java单例模式是最常见的设计模式之一,广泛应用于各种框架.中间件和应用开发中.单例模式实现起来比较简单,基本是每个Java工程师都能信手拈来的,本文将结合多线程.类的加载等知识,系统地介绍一下单例模 ...
- java基础28 单例集合Collection下的List和Set集合
单例集合体系: ---------| collection 单例集合的根接口--------------| List 如果实现了list接口的集合类,具备的特点:有序,可重复 注:集合 ...
- java基础27 单例集合Collection及其常用方法
1.集合 集合是存储对象数据的集合容器 1.1.集合比数组的优势 1.集合可以存储任意类型的数据,数组只能存储同一种数据类型的数据 2.集合的长度是变化的,数组的长度是固定的 1.2.数组:存储 ...
- java单例的几种写法
转载出处:http://cantellow.javaeye.com/blog/838473 第一种(懒汉,线程不安全): public class Singleton { private static ...
- 「Android」单例的五种写法
单例 发现博客园可以很好的设置自己的博客文章的展示,很开心,然后特此发一篇 其实这几种写法大家应该都会的,就权当拿来记录一下吧,以后复习巩固也比较方便. 这篇文章中的代码,来自一篇视频(我想找视频贴上 ...
- java23种设计模式之二: 单例设计模式(6种写法)
目的:在某些业务场景中,我们需要某个类的实例对象的只能有一个,因此我们需要创建一些单例对象. 本文共有6种写法,仅供参考 1.饿汉式 优点: 在多线程情况下,该方法创建的单例是线程安全的(立即加载) ...
- .NET Core中延迟单例另一种写法【.NET Core和.NET Framework的beforefieldinit差异】
1.BeforeFieldInit是什么 前段时间在反编译代码时无意间看到在类中有一个BeforeFieldInit特性,处于好奇的心态查了查这个特性,发现这是一个关于字段初始化时间的特性[提前初始化 ...
- java单例的几种实现方法
java单例的几种实现方法: 方式1: public class Something { private Something() {} private static class LazyHolder ...
随机推荐
- QT博客:QT学习之路
http://www.qter.org/thread-629-1-1.html
- 049 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 11 break语句
049 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 11 break语句 本文知识点:break语句 break语句 break语句前情回顾 1.swi ...
- Java知识系统回顾整理01基础01第一个程序01JDK 安装
一.首先第一步看JDK配置成功后的效果 点WIN键->运行(或者使用win+r) 输入cmd命令 输入java -version 注: -version是小写,不能使用大写,java后面有一个空 ...
- windows10 热点一直显示正在断开中
解决方法: Windows+x,打开"windows Powershell(管理员),执行以下命令:netsh winsock reset 重启电脑,就OK了
- Matlab绘制子图subplot使用攻略
参考:https://jingyan.baidu.com/article/915fc414ad794b51394b20e1.html Matlab绘制子图subplot使用攻略 听语音 原创 | 浏览 ...
- golang 进行grpc调用
参考https://blog.csdn.net/qq_32744005/article/details/105606383 go get google.golang.org/grpc go get - ...
- client: c#+protobuf, server: golang+protobuf
前段时间看到一篇博文<可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)>,他是用C#实现的即时通讯系统,功能强大,界面漂亮. 就想用golang重写服务端,把代码下载 ...
- Linux中断驱动程序
1.中断概念 中断时一种电信号,由硬件设备产生,然后再由中断控制器向处理器发送相应的信号.处理器一经检测到该信号,便中断自己当前正在处理的工作,转而去处理中断.此后,处理器会通知操作系统已经产生中断. ...
- Mock测试你的Spring MVC接口
1. 前言 在Java开发中接触的开发者大多数不太注重对接口的测试,结果在联调对接中出现各种问题.也有的使用Postman等工具进行测试,虽然在使用上没有什么问题,如果接口增加了权限测试起来就比较恶心 ...
- day33 Pyhton logging 模块和包
一内容回顾 try/except try/except/else try/finally try/except try/except/finally try/except/else/finally 报 ...