设计模式-单例模式
时间:2022-07-25
本文章向大家介绍设计模式-单例模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
单列模式是什么?
单列模式是创建型模式的一种,同样一个对象(实例)在内存中只会有一份,并只有一个全局的访问点。单列分为好多种实现,其中有线程安全和线程不安全,大类有懒汉和饿汉;
单列模式可以干嘛?
可以解决一个对象重复的创建和销毁,减少内存的开销,保存只在内存只有一份。就比如:一个学校一般只有一个正校长;
代码实现
懒汉:都是被别人推着才去做的,线程不安全(也有安全)
饿汉: 先创建对象,每次直接返回实例化后单例结果。
比如:
我去吃饭一到饭馆菜都已经上好了,就直接开吃了,这个是饿汉;
我去吃饭一到那里是等了半天,一边上菜一边催,才好不容易把菜上全了,这样的叫懒汉,要别人催才给;
/**
*
* 功能描述:单例(俄汉)
*
* @param:
* @return:
* @auther: csh
* @date: 2020/5/17 10:49
*/
public class HungrySingle {
//创建 HungrySingle 的一个对象 、
private static HungrySingle instance = new HungrySingle();
//让构造函数为 private,这样该类就不会被实例化
private HungrySingle() {
} //获取唯一可用的对象
public static HungrySingle getInstance() {
return instance;
}
public void showMessage() {
System.out.println("Hello World!");
}
}
/**
*
* 功能描述:懒汉(线程不安全)
*
* @param:
* @return:
* @auther: csh
* @date: 2020/5/17 10:55
*/
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton(){}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
/**
* @Auther: csh
* @Date: 2020/5/17 11:27
* @Description:懒汉 (线程安全) 缺点:性能较低
*/
public class LazySingleSafery {
private static LazySingleSafery lazySingleSafery;
private LazySingleSafery(){
}
/**
*
* 功能描述:使用了同步类锁导致性能低下
*
* @param:
* @return:
* @auther: csh
* @date: 2020/5/17 11:32
*/
public static synchronized LazySingleSafery getInstance(){
if(lazySingleSafery == null){
lazySingleSafery = new LazySingleSafery();
}
return lazySingleSafery;
}
}
/**
* @Auther: csh
* @Date: 2020/5/17 11:33
* @Description:双检锁/双重校验锁(DCL,即 double-checked locking)
* 性能较高
*/
public class DoubleCheckLazySingleSafery {
private static DoubleCheckLazySingleSafery instance;
private DoubleCheckLazySingleSafery(){
}
public static DoubleCheckLazySingleSafery getInstance(){
if(instance == null){
synchronized (DoubleCheckLazySingleSafery.class){
if(instance == null){
instance = new DoubleCheckLazySingleSafery();
}
}
}
return instance;
}
}
/**
* @Auther: csh
* @Date: 2020/5/17 11:39
* @Description:登记式/静态内部类 线程安全
*/
public class StaticInnerSingle {
private static class SingleHolder{
private static final StaticInnerSingle INSTANCE = new StaticInnerSingle();
}
private StaticInnerSingle(){
}
public static final StaticInnerSingle getInstance(){
return SingleHolder.INSTANCE;
}
}
/**
* @Auther: csh
* @Date: 2020/5/17 10:43
* @Description:实现
*/
public class SingletonPatternDemo {
public static void main(String[] args) {
//不合法的构造函数
//编译时错误:构造函数 HungrySingle() 是不可见的
//HungrySingle object = new HungrySingle();
//获取唯一可用的对象 饿汉
ExecutorService lazyThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
lazyThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("饿汉(安全)"+ HungrySingle.getInstance());
}
});
}
//懒汉 线程不安全
ExecutorService hungryThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
hungryThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("懒汉(不安全)"+LazySingleton.getInstance());
}
});
}
//懒汉 线程安全 性能低
ExecutorService hungrySaferyThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
hungrySaferyThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("懒汉(安全)"+LazySingleSafery.getInstance());
}
});
}
//懒汉 线程安全 性能高
ExecutorService DoubleCheckThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
DoubleCheckThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("懒汉双重检查(安全)"+DoubleCheckLazySingleSafery.getInstance());
}
});
}
//懒汉 线程安全 性能高
ExecutorService staticInnerSingleThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
staticInnerSingleThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("登记式/静态内部类(安全)"+StaticInnerSingle.getInstance());
}
});
}
}
}
结果
"C:Program FilesJavajdk1.8.0_181binjava.exe" "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.3libidea_rt.jar=58612:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.3bin" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_181jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_181jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_181jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_181jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_181jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_181jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_181jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_181jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_181jrelibextnashorn.jar;C:Program FilesJavajdk1.8.0_181jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_181jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_181jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_181jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_181jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_181jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_181jrelibjce.jar;C:Program FilesJavajdk1.8.0_181jrelibjfr.jar;C:Program FilesJavajdk1.8.0_181jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_181jrelibjsse.jar;C:Program FilesJavajdk1.8.0_181jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_181jrelibplugin.jar;C:Program FilesJavajdk1.8.0_181jrelibresources.jar;C:Program FilesJavajdk1.8.0_181jrelibrt.jar;D:ideaWorkSpacedesign-modeltargetclasses" com.hong.base.singlemodel.SingletonPatternDemo
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@710f2fc4
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@1bd08742
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
最后,判断一个对象是不是单列只需要看对象里面有没有private 类名 (){} 如果有肯定是单例。
- 基于Logstash的自动化运维系统实现
- 简谈RGW的index shard计算
- Blackpearl 的 Impersonate
- SparkMLLib中基于DataFrame的TF-IDF
- 运用Python实现WordPress网站大规模自动化发布文章
- 基于java的中文分词工具ANSJ
- 基于DF的Tokenizer分词
- 基于pyenv和virtualenv搭建python多版本虚拟环境
- 基于DataFrame的StopWordsRemover处理
- 案例:Spark基于用户的协同过滤算法
- 请别再问我Spark的MLlib和ML库的区别
- Spark的Ml pipeline
- EasyUI 创建 CRUD 应用
- phoenix二级索引
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 重拾Java Web应用的基础体系结构
- 使用SAP C4C自定义BO实现自定义的Number Range
- 限流算法简介及Guava RateLimiter令牌桶限流介绍
- K8S的名称空间创建&&版本的升级、回滚操作
- SAP Cloud for Customer CLR(Code List Restriction)的一种高级用法
- SAP WebClient UI One Hit Navigation的实现方法
- 【打包构建】Mac下使用expect实现执行sudo命令时自动输入密码
- ASP.NET Core 奇淫技巧之SPA部署
- SAP Cloud for Customer Rule Editor的使用方法和底层工作原理
- (数据科学学习手札94)QGIS+Conda+jupyter玩转Python GIS
- 72-STM32+ESP8266+AIR202基本控制篇-移植使用-移植Android的MQTT包到自己的工程项目
- 用上Latex实现编辑伪代码
- TensorFlow交叉熵函数(cross_entropy)·理解
- 第05期:Prometheus 数据查询(一)
- 技术分享 | MySQL 复制那点事 - Seconds_behind_Master 参数调查笔记