单例模式的要点

单例模式属于创建型模式

三个要点:

  • 某个类只能有一个实例
  • 它必须自己创建这个实例
  • 它必须自行向整个系统提供这个实例

单例模式的特点

  • 单例类只能有一个实例
  • 单例类必须自己创建自己的唯一的实例
  • 单例类必须给所有其他对象提供这一实例

饿汉式单例类

线程安全,实现简单

优点:没有加锁,执行效率高

缺点:类在加载的时候就初始化,浪费内存

public class Singleton {

    private final static Singleton SINGLETON = new Singleton();

    private Singleton() {

    }

    public static Singleton getInstance() {
return SINGLETON;
}
}

另一种实现:

public class Singleton {

    private static Singleton instance;

    static {
instance = new Singleton();
} private Singleton() { } public static Singleton getInstance() {
return instance;
}
}

懒汉式单例类

一:懒汉式,线程不安全

实现简单

没有加锁,在多线程情况下不安全

public class Singleton {

    private static Singleton instance;

    private Singleton() {
} public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

二:懒汉式,线程安全

实现简单,线程安全

优点:第一次调用的时候才初始化,避免了消耗内存

缺点:加了synchronized关键字,效率低

public class Singleton {

    private static Singleton instance;

    private Singleton() {
} public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

三:懒汉式,线程不安全

实现简单,线程不安全

做不到单例

public class Singleton {

    private static Singleton instance;

    private Singleton() {
} public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
}

四:懒汉式,双检锁/双重校验锁

JDK1.5起

线程安全,实现较复杂

优点:线程安全,延迟加载,效率较高

注意:volatile关键字修饰很关键

public class Singleton {

    private static volatile Singleton instance;

    private Singleton () {
} public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

五:懒汉式,静态内部类

优点:线程安全,延迟加载,效率较高

原理:类的静态属性只会在第一次加载类的时候初始化。在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。

public class Singleton {

    private Singleton() {
} private static class LazySingletonInstance {
private static final Singleton instance = new Singleton();
} public static Singleton getInstance() {
return LazySingletonInstance.instance;
}
}

六:懒汉式,枚举

JDK1.5起

线程安全,实现简单

优点:更简洁,自动支持序列化机制,绝对防止多次实例化

public enum  Singleton {
INSTANCE;
public void whateverMethod() { }
}

总结

一般而言,不建议使用第1、2、3种,建议使用饿汉方式。只有在要明确实现 lazy loading效果时,才会使用第 5 种静态内部类方式。如果涉及到反序列化创建对象时,可以尝试使用第 6 种枚举方式。如果有其他特殊的需求,可以考虑使用第 4 种双检锁方式

这个世界上只有一个你之Java设计模式:单例模式的更多相关文章

  1. JAVA设计模式-单例模式(Singleton)线程安全与效率

    一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...

  2. 【设计模式】Java设计模式 - 单例模式

    [设计模式]Java设计模式 - 单例模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 分享学习心得,欢迎指正,大家一起学习成长! 原创作品,更多关注我CSDN: ...

  3. java设计模式单例模式 ----懒汉式与饿汉式的区别

    常用的五种单例模式实现方式 ——主要: 1.饿汉式(线程安全,调用率高,但是,不能延迟加载.) 2.懒汉式(线程安全,调用效率不高,可以延时加载.) ——其他: 1.双重检测锁式(由于JVM底层内部模 ...

  4. Java设计模式の单例模式

    -------------------------------------------------- 目录 1.定义 2.常见的集中单例实现 a.饿汉式,线程安全 但效率比较低 b.单例模式的实现:饱 ...

  5. Java设计模式 - - 单例模式 装饰者模式

    Java设计模式 单例模式 装饰者模式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 静态代理模式:https://www.cnblogs.com/StanleyBlogs/p/1 ...

  6. Java 设计模式 —— 单例模式

    1. 概念: 单例模式是一种常用的软件设计模式.核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果 ...

  7. JAVA设计模式——单例模式

    单例模式的定义: Ensure a class has only one instance, and provide a global point of access to it.( 确保某一个类只有 ...

  8. Java设计模式-单例模式(Singleton)

    单例对象(Singleton)是一种常用的设计模式.在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在.这样的模式有几个好处: 1.某些类创建比较频繁,对于一些大型的对象,这是一笔 ...

  9. Java设计模式 - 单例模式 (懒汉方式和饿汉方式)

    概念: Java中单例模式是一种常见的设计模式,单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式的写法有好几种,这 ...

随机推荐

  1. ext文件系统机制原理剖析

    本文转载自ext文件系统机制原理剖析 导语 将磁盘进行分区,分区是将磁盘按柱面进行物理上的划分.划分好分区后还要进行格式化,然后再挂载才能使用(不考虑其他方法).格式化分区的过程其实就是创建文件系统. ...

  2. Kubernetes和docker----1.开始使用k8s和docker

    开始使用Kubernetes和docker docker命令 运行一个容器 docker run busybox echo "Hello world" 构建容器镜像 docker ...

  3. Oracle kill locked sessions

    select * from v$locked_object; select * from v$session where sid in (select session_id from v$locked ...

  4. 使用Docker创建MongoDb服务

    使用Docker创建MongoDb服务 1.先拉mongodb镜像 docker pull mongodb:4.2.5 2.创建映射目录 创建mongo映射目录,用于存放后面的相关东西. mkdir ...

  5. 第七届蓝桥杯JavaB组——第7题剪邮票

    题目: 剪邮票 如[图1.jpg], 有12张连在一起的12生肖的邮票. 现在你要从中剪下5张来,要求必须是连着的. (仅仅连接一个角不算相连) 比如,[图2.jpg],[图3.jpg]中,粉红色所示 ...

  6. NodeJs 入门到放弃 — 常用模块及网络爬虫(二)

    码文不易啊,转载请带上本文链接呀,感谢感谢 https://www.cnblogs.com/echoyya/p/14473101.html 目录 码文不易啊,转载请带上本文链接呀,感谢感谢 https ...

  7. 链表算法题之中等级别,debug调试更简单

    文章简述 大家好,本篇是个人的第 5 篇文章 从本篇文章开始,分享关于链表的题目为中等难度,本次共有 3 道题目. 一,两数相加 1.1 题目分析 题中写到数字是按照逆序的方式存储,从进位的角度看,两 ...

  8. C语言中指针和多维数组

    指针和多维数组 数组名是特殊的指针 数组是一个特殊的指针,多维数组也是更为复杂的数组,它们的关系是什么样的呢? 我们通过一个简单的例子来比较形象的了解指针和多维数组: int a[2][3]; 这是一 ...

  9. Shiro 反序列化漏洞利用

    环境搭建 docker pull medicean/vulapps:s_shiro_1 docker run -d -p 80:8080 medicean/vulapps:s_shiro_1 # 80 ...

  10. Why系列:谨慎使用delete

    题外话 这里大家可能要笑了,这不就一个操作符吗,还用单独来讲. 有这时间,还不如去看看react源码,vue源码. 我说:react源码会去看的,但是这个也很重要. delete你了解多少 这里提几个 ...