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设计模式之单例模式你真的会了吗?(懒汉式篇)的更多相关文章

  1. java 设计模式之单例模式

    -------Success is getting what you want, happiness is wanting what you get. java设计模式之单例模式(Singleton) ...

  2. 折腾Java设计模式之单例模式

    博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access ...

  3. Java设计模式之单例模式(七种写法)

    Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleto ...

  4. Java 设计模式之单例模式(一)

    原文地址:Java 设计模式之单例模式(一) 博客地址:http://www.extlight.com 一.背景 没有太多原由,纯粹是记录和总结自己从业以来经历和学习的点点滴滴. 本篇内容为 Java ...

  5. java设计模式1——单例模式

    java设计模式1--单例模式 1.单例模式介绍 1.1.核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 1.2.常见场景 1.3.单例模式的优点 1.4.常见的五种单例模式实现 ...

  6. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  7. java设计模式- (1)单例模式

    参加校园招聘的笔试,发现公司都会考一些java设计模式,所以上网查询相关内容,总结常用的几种单例模式. 单例模式(Singleton Pattern)是 Java中最简单的设计模式之一.这种类型的设计 ...

  8. [转]JAVA设计模式之单例模式

    原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...

  9. java设计模式之单例模式(七种方法)

    单例模式:个人认为这个是最简单的一种设计模式,而且也是在我们开发中最常用的一个设计模式. 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个 ...

随机推荐

  1. js数组reduce解析及使用示例

    reduce() 简单说,reduce()可以对数组中的每个元素执行一个由您提供的reducer函数(升序执行),函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后将其结果汇总为单个返 ...

  2. vue-cli2 项目中使用node-sass

    公司的项目,换了个电脑要重新安装一下依赖,但是直接npm install的时候报错了,提示node-sass未安装成功. 然后直接npn install node-sass --save 的时候还是下 ...

  3. 使用SignalR ASP.NET Core来简单实现一个后台实时推送数据给Echarts展示图表的功能

    什么是 SignalR ASP.NET Core ASP.NET Core SignalR 是一种开放源代码库,可简化将实时 web 功能添加到应用程序的功能. 实时 web 功能使服务器端代码可以立 ...

  4. JavaWeb 基础知识补充

    软件架构 1. C/S: Client/Server 客户端/服务器端         * 在用户本地有一个客户端程序,在远程有一个服务器端程序         * 如:QQ,迅雷...        ...

  5. Hadoop完整搭建过程(一):本地模式

    1 本地模式 本地模式是最简单的模式,所有模块都运行在一个JVM进程中,使用本地文件系统而不是HDFS. 本地模式主要是用于本地开发过程中的运行调试用,下载后的Hadoop不需要设置默认就是本地模式. ...

  6. java多种文件复制方式以及效率比较

    1.背景 java复制文件的方式其实有很多种,可以分为 传统的字节流读写复制FileInputStream,FileOutputStream,BufferedInputStream,BufferedO ...

  7. Spring-@PostConstruct注解

    @PostConstruct注解 @PostConstruct注解好多人以为是Spring提供的.其实是Java自己的注解. Java中该注解的说明:@PostConstruct该注解被用来修饰一个非 ...

  8. JavaScript 简写技巧

    1. 声明变量 //普通写法 let x; let y = 20; //简写 let x, y = 20; 2. 给多个变量赋值 //普通写法 let a, b, c; a = 5; b = 8; c ...

  9. Java基础练习——读心术(扑克牌魔术——21张扑克牌)

    Java基础练习--读心术(扑克牌魔术--21张扑克牌) 用到了Scanner,for循环,if-else语句,集合,线程的Thread.sleep()方法 话不多说,直接上代码!

  10. Day01_10_Scanner 接收用户输入

    Scanner函数 import java.util.Scanner; class ScannerTest { public static void main(String[] args){ Syst ...