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 ...
随机推荐
- CAS 原子操作
理会CAS和CAS: 有时候面试官面试问你的时候,会问,谈谈你对CAS的理解,这时应该有很多人,就会比较懵,当然,我也会比较懵,当然我和很多人的懵不同,很多人可能,并不知道CAS是一个什么东西,而在我 ...
- 03 sublime text3下配置Java的编译运行环境
参考如下文章,加入了自己的干货: https://blog.csdn.net/qq_38295511/article/details/81140069 https://blog.csdn.net/qq ...
- matlab中repmat函数的用法
转载:https://blog.csdn.net/facetosea1/article/details/83573859 B = repmat(A,m,n)B = repmat(A,[m n])B = ...
- Oracle Database XE 11gR2 SQL 命令行的显示调整
操作系统:Windows 10 x64 Oracle Database XE 11gR2 参考:在cmd命令行使用sqlplus时的页面显示问题 通过 cmd 命令行或运行 SQL 命令行查看一张表的 ...
- css引入本地字体
1.首先创建一个字体 @font-face { font-family: 'number_font'; //创建一个number_font字体名称 src: url('../../../style/F ...
- day20 Pyhton学习 面向对象-成员
一.类的成员 class 类名: # 方法 def __init__(self, 参数1, 参数2....): # 属性变量 self.属性1 = 参数1 self.属性2 = 参数2 .... # ...
- mac安装go环境
下载pkg文件 https://golang.google.cn/dl/ sudo vim /etc/profile export GOROOT=/usr/local/go export GOPA ...
- python 爬取简书评论
import json import requests from lxml import etree from time import sleep url = "https://www.ji ...
- 极简 Node.js 入门 - 5.3 静态资源服务器
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- Pytest学习(一)- 入门及基础
前言 十一也赶上自己刚出院,本想在十一放假前用假期刷完Pytest的,结果被希洛克神话吸引,再次回归毒奶粉,一直奋斗到距离上班还有两天,引导石刷没了,就没了智慧. 当然也没出过神话,结果一怒之下卸载, ...