java设计模式之单例模式你真的会了吗?(懒汉式篇)
java设计模式之单例模式你真的会了吗?(懒汉式篇)
一、什么是单例模式?
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
二、单例模式之懒汉式有什么特点以及优缺点?
- 构造方法私有化
- 在第一次被使用时构建实例,延迟初始化
- 对外提供统一的静态工厂方法返回实例
- 优点:需要的时候才实例化所以节约内存。
- 缺点:第一次加载时不够快,多线程使用时不必要的同步开销大。
三、懒汉式单例的代码进阶(1)
public class LazySingleton implements Serializable {
private static final long serialVersionUID = -777413485350310911L;
private LazySingleton() {}
private static LazySingleton lazySingleton = null;
public static LazySingleton getInstance() {
if(lazySingleton == null){
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
- 上面的代码存在着最明显的问题就是在多线程的环境下无法保证单例。
四、懒汉式单例的代码进阶(2)
public class LazySingleton implements Serializable {
private static final long serialVersionUID = -777413485350310911L;
private LazySingleton() {}
private static LazySingleton lazySingleton = null;
synchronized public static LazySingleton getInstance() {
if(lazySingleton == null){
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
- 上面的代码在getInstance()方法前面增加了关键字synchronized进行线程锁,以处理多个线程同时访问的问题。但是,这样虽然解决了线程安全问题,但是每次调用getInstance()时都需要进行线程锁定判断,在多线程高并发访问环境中,将会导致系统性能大大降低。
五、懒汉式单例的代码进阶(3)
public class LazySingleton implements Serializable {
private static final long serialVersionUID = -777413485350310911L;
private LazySingleton() {}
private static LazySingleton lazySingleton = null;
//double check
public static LazySingleton getInstance() {
if(lazySingleton == null){
synchronized(LazySingleton.class){
if(lazySingleton == null){
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
}
- 上面的代码采用synchronized和double check的方式成功解决了线程安全问题以及提高了多线程下的性能,但是性能任然不够理想。
六、懒汉式单例的代码进阶(4)
public class LazySingleton implements Serializable {
private static final long serialVersionUID = -777413485350310911L;
private LazySingleton() {}
public static LazySingleton getInstance() {
return LazyInnerSingleton.INSTANCE;
}
/**
* 利用内部类的特性创建单例
*/
private static class LazyInnerSingleton {
private static final LazySingleton INSTANCE = new LazySingleton();
}
}
- 上面利用内部类的特性创建单例既保证了线程安全(由jvm的类加载机制提供)问题又提高了性能,但是还是存在着一个问题:利用反射依然可以破坏“单例”,所以继续改进代码。
六、懒汉式单例的代码进阶(5)
public class LazySingleton implements Serializable {
private static final long serialVersionUID = -777413485350310911L;
private LazySingleton() {
//防止利用反射破坏单例
if(LazyInnerSingleton.INSTANCE != null){
throw new RuntimeException("不允许构建多个实例!");
}
}
public static LazySingleton getInstance() {
return LazyInnerSingleton.INSTANCE;
}
/**
* 利用内部类的特性创建单例
*/
private static class LazyInnerSingleton {
private static final LazySingleton INSTANCE = new LazySingleton();
}
}
- 在构造方法中抛出一个异常以防止通过反射破坏单例。
PS:如果你看到了这篇文章,并且觉得对你有帮助,请给个关注和点赞,谢谢!
java设计模式之单例模式你真的会了吗?(懒汉式篇)的更多相关文章
- java 设计模式之单例模式
-------Success is getting what you want, happiness is wanting what you get. java设计模式之单例模式(Singleton) ...
- 折腾Java设计模式之单例模式
博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access ...
- Java设计模式之单例模式(七种写法)
Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleto ...
- Java 设计模式之单例模式(一)
原文地址:Java 设计模式之单例模式(一) 博客地址:http://www.extlight.com 一.背景 没有太多原由,纯粹是记录和总结自己从业以来经历和学习的点点滴滴. 本篇内容为 Java ...
- java设计模式1——单例模式
java设计模式1--单例模式 1.单例模式介绍 1.1.核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 1.2.常见场景 1.3.单例模式的优点 1.4.常见的五种单例模式实现 ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- java设计模式- (1)单例模式
参加校园招聘的笔试,发现公司都会考一些java设计模式,所以上网查询相关内容,总结常用的几种单例模式. 单例模式(Singleton Pattern)是 Java中最简单的设计模式之一.这种类型的设计 ...
- [转]JAVA设计模式之单例模式
原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...
- java设计模式之单例模式(七种方法)
单例模式:个人认为这个是最简单的一种设计模式,而且也是在我们开发中最常用的一个设计模式. 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个 ...
随机推荐
- ASP.NET Core分布式日志系统ELK实战演练
一.ELK简介 ELK是Elasticsearch.Logstash和Kibana首字母的缩写.这三者均是开源软件,这三套开源工具组合起来形成了一套强大的集中式日志管理平台. • Elastics ...
- 打造云原生大型分布式监控系统系列文章-腾讯工程师roc
附上本系列文章链接 打造云原生大型分布式监控系统(一): 大规模场景下 Prometheus 的优化手段 打造云原生大型分布式监控系统(二): Thanos 架构详解 打造云原生大型分布式监控系统(二 ...
- vue-cli2 项目中使用node-sass
公司的项目,换了个电脑要重新安装一下依赖,但是直接npm install的时候报错了,提示node-sass未安装成功. 然后直接npn install node-sass --save 的时候还是下 ...
- Mokito 单元测试与 Spring-Boot 集成测试
Mokito 单元测试与 Spring-Boot 集成测试 版本说明 Java:1.8 JUnit:5.x Mokito:3.x H2:1.4.200 spring-boot-starter-test ...
- Windows命令行学习(系统信息收集)
echo off :关闭回显 echo on :开启回显 net user :显示主机的电脑用户 ipconfig /displaydns:后面的 /displaydns是显示当前电脑所缓存的dns信 ...
- Java常用工具+类库合集
1 常用工具 JVisual vm:可以直接通过软件包下载,支持本地以及远程JVM监控 JMH:Java Microbenchmark Harness,测试基准组件,精度可达纳秒级 JITWatch: ...
- 数据结构之链表(JavaScript描述)
链表数据结构 链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续防止的.每个元素由一个存储元素本身的节点和一个只想下一个元素的引用(也称为指针或链接)组成 类似的例子 创建链表 ...
- 【SpringBoot源码分析】-Bean的加载过程
-- 以下内容均基于2.1.8.RELEASE版本 在<SpringBoot启动过程的分析>系列文章中简要的对SpringBoot整体的启动流程作了梳理,但并未针对诸多细节进行分析.前面的 ...
- 使用Tensorflow Object Detection进行训练和推理
整体流程(以PASCAL VOC为例) 1.下载PASCAL VOC2012数据集,并将数据集转为tfrecord格式 2.选择并下载预训练模型 3.配置训练文件configuration(所有的训练 ...
- k8s job 控制器
Job控制器可以执行3种类型的任务 1)一次性任务 2)串式任务 spec.completions 3)并形式任务 spec.parallelism 默认Job执行后,不会自动删除,需要手动删除,例如 ...