深入单例模式

devtools/2024/9/23 14:30:04/

1. 饿汉模式

饿坏了,上来就先实例化一个对象,好处是代码简单,坏处是这个对象后面如果一直用不到,就是个浪费。

public class A{

    private static A a = new A();

    private A(){}

    public static A getInstance(){

        return a;

    }

}

2. 懒汉模式

懒洋洋的,用到的时候才抱佛脚。最简单的懒汉模式如下,存在线程安全问题。

public static class A{

    private static A a=null;

    private A(){}

    public static A getInstance(){

        if(a==null){

            a=new A();

        }

        return a;

    }

}

终极解决办法是使用DCL(double check lock)加volatile,如下所示:

public static class A{

    private static volatile A a=null;

    private A(){}

    public static A getInstance(){

        if(a==null){

            synchronized (A.class){

                if(a==null){

                    a=new A();

                }

            }

        }

        return a;

    }

}

  • DCL其实就是一锁二判三更新(在一锁之前加一个判断,提高并发时的效率,不需要每次一上来都先锁住消耗性能)。
  • 加volatile的目的是防止第8行发生指令重排。

第8行在底层会有3个操作:

  1. 分配一块内存
  2. 初始化这块内存(一般是调用类的构造函数)
  3. 将这块内存赋给变量(如上代码中是变量a)

如果在变量a不加volatile,上面的步骤可能发生指令重排变成1、3、2,导致a先等于一块没有初始化(2还未执行)或初始化一半(2执行了一半)的内存,这时候如果代码其他部分(不需要获取A.class的锁的部分)访问了a变量,就会读到预料外的值。

这有点类似于数据库里的“脏读”,在事务处理中的数据被该事务外读到。

 


http://www.ppmy.cn/devtools/97819.html

相关文章

Java面试题———MySql篇③

目录 1.查询语句执行流程 2.索引的数据结构是什么 3.数据库中的锁有哪些 4.MySQL日志类型 5.MySQL主从复制的流程 6.谈谈你对sql的优化的经验 1.查询语句执行流程 一条查询语句到达MySQL数据库之后,数据库中的各个组件会按照顺序执行自己的任务 首先是连接器…

取证工具 ElcomSoft iOS Forensics Toolkit: 在 Windows 中加载 HFS 镜像

天津鸿萌科贸发展有限公司是 ElcomSoft 系列取证软件的授权代理商。 Elcomsoft iOS Forensics Toolkit 功能简介 Elcomsoft iOS Forensics Toolkit 软件工具包适用于取证工作,对 iPhone、iPad 和 iPod Touch 设备执行完整文件系统和逻辑数据采集。对设备文件系统制…

8个我平时每天都会看的网站,涵盖办公、娱乐、学习等

分享8个我平时每天都会看的网站,涵盖办公、娱乐、学习等多种类别,试过就知道有多好用! 1、MyFreeMP3 tools.liumingye.cn/music/#/ 一个可以免费听歌的平台,不用充会员,里面收录了大多数的国内外知名流行歌手、乐队的…

vue3 响应式 API:watch()、watchEffect()

watch() 基本概念 watch()用于监视响应式数据的变化,并在数据变化时执行相应的回调函数。可以监视单个响应式数据、多个响应式数据的组合,或者一个计算属性。 返回值 返回一个函数,调用这个函数可以停止监视。 特点 watch() 默认是懒侦听的&…

Ansible可视化管理之web界面集成使用探究(未完待续)

一、前言 因某集成商管理的客户资源涉及4A接入管控要求,其中密码必须3个月更新一次,随着纳管主机的数量增多,手动去修改密码变得不现实,考虑无侵入性和资源耗用,便捷性等因素,首先选用Ansible作为此需求的…

硬件工程师必须掌握的MOS管详细知识

MOS管,全称为金属-氧化物半导体场效应晶体管(Metal-Oxide-Semiconductor Field-Effect Transistor,MOSFET),是一种重要的半导体器件,广泛应用于电子工业中各种电路的开关、放大、调制、数字电路和模拟电路等…

Oracle(66)什么是虚拟列(Virtual Column)?

虚拟列(Virtual Column)是数据库中的一种特殊列,它的值并不直接存储在数据库中,而是根据其他列的值通过表达式计算得到的。在Oracle数据库中,虚拟列的值是动态计算的,因此不会占用额外的存储空间。这种功能…

Windows和Linux系统查看设备IP的方法

Windows 通过命令提示符 1、打开“开始”菜单,搜索“cmd”或“命令提示符”并打开 2、在命令提示符窗口中,输入ipconfig 3、查找与网络连接相关的信息,通常是“无线局域网适配器 WLAN”或“以太网适配器”,然后找到“IPv4 地址…