目录

1.概念

2.实现


1.概念

1.1 什么是单例模式

单例模式能保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例.

这一点在很多场景上都需要。比如 JDBC 中的 DataSource 实例就只需要一个

1.2 单例模式分类

单例模式具体的实现方式, 分成 "饿汉" 和 "懒汉" 两种.

所谓”饿汉“模式,就是指程序启动则立刻创建实例,可以形象理解为”饿汉“迫不及待想要吃饭(创建实例)。但不管是否使用都创建对象可能会浪费内存,但是线程安全。

而”懒汉“模式,则是程序启动时不着急创建实例,等到真正使用时再创建,就好像”懒汉“只有在一件事真正需要被做时他才去做,绝对不可能提前。减少了资源浪费,线程不安全,但可以通过加锁来实现线程安全。

2.实现

2.1 饿汉模式

class Singleton{private static Singleton instance=new Singleton();//静态成员表示实例private Singleton(){};//构造方法私有化public static Singleton getInstance(){return instance;};
}

这里我们通过静态成员表示实例(唯一性)+构造方法私有化(堵住new创建新实例的口子)从而实现了单例模式。当Singleton类被加载时就会执行此处实例化操作,突出了”饿汉“的特点,非常急迫。那么段代码在多线程的情况下会存在线程安全问题吗?答案是不会,因为类加载的方式是按需加载,且只加载一次。

2.2 懒汉模式-单线程版

class Singleton{private static Singleton instance=null();//不立刻创建实例private Singleton(){};//私有化构造方法public static Singleton getInstance(){if(instance==null){instance=new Singleton();}return instance;}
}

这个单例模式的代码放在单线程情况下是完全没有问题的,但是假如在多线程的状态下

线程安全问题发生在首次创建实例时. 如果在多个线程中同时调用 getInstance 方法, 就可能导致 创建出多个实例.

一旦实例已经创建好了, 后面再多线程环境调用 getInstance 就不再有线程安全问题了(不再修改 instance 了)

所以我们需要进行加锁操作来解决这个问题。

2.3 懒汉模式-多线程版

class Singleton{private static Singleton instance=null;//不立刻创建实例private Singleton(){};//私有化构造方法public synchronized static Singleton getInstance(){if(instance==null){instance=new Singleton();}return instance;}
}

2.4 懒汉模式-多线程版(改进)

我们仔细观察上面的代码,可以发现一些改进的空间。加锁 / 解锁是一件开销比较高的事情. 而懒汉模式的线程不安全只是发生在首次创建实例的时候. 因此后续使用的时候, 不必再进行加锁了。其次 由于可能有多个线程来尝试获取我们的实例,jvm可能会对此进行优化产生内存可见性问题(只是可能),所以我们保守起见还是应该加上volatile关键字

于是我们得到以下改进方案:

1.加锁

2.双重if判断

3.volatile

class Singleton{private static Singleton instance=null;//不立刻创建实例private Singleton(){};//私有化构造方法public static Singleton getInstance(){if(instance==null){synchronized (Singleton.class){//类名.class返回的是一个class对象if(instance==null){instance=new Singleton();}}}return instance;}
}

这里我们需要着重理解一下双重if的意思,最外层的if是判断当前前是否已经把 instance 实例创建出来了。如果已经创建就不需要加锁了。当多线程首次调用 getInstance, 大家可能都发现 instance 为 null, 于是又继续往下执行来竞争锁, 其中竞争成功的线程, 再完成创建实例的操作。当这个实例创建完成后,其他竞争的线程就被里层的if挡住了,不会继续创建其他实例。最后就是加上volatile修饰,防止出现内存可见性问题。

java多线程——单例模式相关推荐

  1. Java多线程---单例模式(有趣易懂版)

    单例模式 单例对象的类只能允许一个实例存在. 特征 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类必须给所有其他对象提供这一实例. 饿汉模式 在类加载时,完成实例化,用时直接用.可 ...

  2. Java多线程之单例模式在多线程环境下的安全问题

    Java多线程之单例模式在多线程环境下的安全问题 目录: 单例模式基本概念 单线程下的单例模式 多线程下的单例模式 单例模式volatile分析 1. 单例模式基本概念 基本概念转载自:单例模式|菜鸟 ...

  3. java 多线程的单例模式,Java多线程中的单例模式两种实现方式

    Java多线程中的单例模式 一.在多线程环境下创建单例 方式一: package com.ietree.multithread.sync; public class Singletion { priv ...

  4. Java多线程案例之单例模式(懒汉,饿汉,枚举)

    ⭐️前面的话⭐️ 本篇文章将介绍Java多线程中的几个典型案例之单例模式,所谓单例模式,就是一个类只有一个实例对象,本文将着重介绍在多线程的背景下,单例模式的简单实现.

  5. Java多线程:多线程同步安全问题的 “三“ 种处理方式 ||多线程 ”死锁“ 的避免 || 单例模式”懒汉式“的线程同步安全问题

    Java多线程:多线程同步安全问题的 "三" 种处理方式 ||多线程 "死锁" 的避免 || 单例模式"懒汉式"的线程同步安全问题 每博一文 ...

  6. java 线程 单例_多线程单例模式

    多线程单例模式 原文:https://blog.csdn.net/u011726005/article/details/82356538 1. 饿汉模式 使用饿汉模式实现单例是十分简单的,并且有效避免 ...

  7. 40个Java多线程问题总结

    (转) 这篇文章作者写的真是不错 40个问题汇总 1.多线程有什么用? 一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了,还管它有什么用?在我看来,这个回答更扯淡.所谓"知其然知其所 ...

  8. Java多线程的同步机制(synchronized)

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个 ...

  9. 史上最全 Java 多线程面试题及答案

    这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题. 这些多线程的问题,有些来源于各大网站.有些来源于自己的思考.可能有些问题网上有.可能有些问题对应的答案也有.也可能有些各位网友也 ...

最新文章

  1. 技术人如何搭建自己的技术博客
  2. redux模块化demo
  3. 网络基础---物理层
  4. Python 之glob模块
  5. 4.3.2 用jQuery进行异步加载(1)
  6. python round保留小数位_Python-其他-round()保留小数位时遇到的问题
  7. 传递一个父id返回所有子id的用法,可用于删除父级以下的所有子级
  8. 后缀数组三·重复旋律3
  9. 非阻塞connect的作用及代码示例
  10. 检查Oracle数据库和PDB数据库的大小
  11. angular6添加子路由_如何将Ionicons添加到Angular 6应用
  12. 超声光学成像突破衍射极限
  13. if控制条件——BMI
  14. 如何通俗易懂地理解什么叫泛型?
  15. PDPS软件:机器人抓手工具运动机构制作与仿真运行测试
  16. 上市公司控股股东的条件
  17. GitHub + jsDelivr + PicGo + Imagine 打造稳定快速、高效免费图床
  18. MySQL 如何隐藏客户姓名、手机号或者身份证号中的部分信息
  19. 树莓派:获取传感器数据
  20. 为什么很多人买基金总不赚钱

热门文章

  1. vue+elementui调用tiny(熊猫压缩)接口进行图片压缩
  2. 新版联想电脑管家怎么打开护眼模式
  3. libevent 返回中文乱码问题
  4. 记一次,编译MuseScore的经历
  5. 遥感与GIS相关期刊
  6. python获取微信指数
  7. FFMPEG 之视频播放
  8. 线性结构和非线性结构 - 数据结构基础
  9. 怎么用C#制作印章(转自:http://dev.csdn.net/author/Knight94/d670c121ca4d49a09160cef171867f2d.html)
  10. 实现解决843端口安全策略问题心得