java:java学习笔记之java单例模式的简单理解和使用(代码片段)

JMW1407 JMW1407     2022-12-09     284

关键词:

Java单例模式的简单理解和使用

Java单例模式

1、饿汉式单例的实现如下:

//饿汉式实现
public class SingleB 
    private static final SingleB INSTANCE = new SingleB();
    private SingleB() 
    public static SingleB getInstance() 
        return INSTANCE;
    

2、懒汉式终极版本:volatile

// Version 4 
public class Single4 
    private static volatile Single4 instance;
    private Single4() 
    public static Single4 getInstance() 
        if (instance == null) 
            synchronized (Single4.class) 
                if (instance == null) 
                    instance = new Single4();
                
            
        
        return instance;
    


主要在于singleton = new Singleton()这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情:

  • 1、给 singleton 分配内存
  • 2、调用 Singleton 的构造函数来初始化成员变量,形成实例
  • 3、将singleton对象指向分配的内存空间(执行完这步 singleton才是非 null 了)

但是在 JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2

  • 如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。

再稍微解释一下,就是说,由于有一个『instance已经不为null但是仍没有完成初始化』的中间状态,而这个时候,如果有其他线程刚好运行到第一层if (instance == null)这里,这里读取到的instance已经不为null了,所以就直接把这个中间状态的instance拿去用了,就会产生问题。

  • 这里的关键在于——线程T1对instance的写操作没有完成,线程T2就执行了读操作

volatile关键字的作用

volatile关键字的一个作用是禁止指令重排,把instance声明为volatile之后,对它的写操作就会有一个内存屏障,这样,在它的赋值完成之前,就不用会调用读操作。

  • 注意:volatile阻止的不singleton = newSingleton()这句话内部[1-2-3]的指令重排,而是保证了在一个写操作([1-2-3])完成之前,不会调用读操作(if(instance == null))

3、Effective Java 1 —— 静态内部类

// Effective Java 第一版推荐写法
public class Singleton 
    private static class SingletonHolder 
        private static final Singleton INSTANCE = new Singleton();
    
    private Singleton ()
    public static final Singleton getInstance() 
        return SingletonHolder.INSTANCE;
    

这种写法非常巧妙:

  • 对于内部类SingletonHolder,它是一个饿汉式的单例实现,在SingletonHolder初始化的时候会由ClassLoader来保证同步,使INSTANCE是一个真·单例。
  • 同时,由于SingletonHolder是一个内部类,只在外部类的SingletongetInstance()中被使用,所以它被加载的时机也就是在getInstance()方法第一次被调用的时候。
  • 它利用了ClassLoader来保证了同步,同时又能让开发者控制类加载的时机。从内部看是一个饿汉式的单例,但是从外部看来,又的确是懒汉式的实现。

4、5.2 Effective Java 2 —— 枚举

// Effective Java 第二版推荐写法
public enum SingleInstance 
    INSTANCE;
    public void fun1()  
        // do something
    


// 使用
SingleInstance.INSTANCE.fun1();

参考

1、Hi,我们再来聊一聊Java的单例吧

java单例模式之学习

经典的单例模式:   publicclassSingleton   privatestaticSingletonuniqueInstance=null;   privateSingleton()     //Existsonlytodefeatinstantiation.      publicstaticSingletongetInstance()     if(uniqu 查看详情

单例模式的学习笔记

java设计模式之单例模式什么叫单例模式(实例有且只有一个)/*单例模式Singleton应用场合:有些对象只需要一个实例就够了作用:保证整个应用程序中某个实例有且只有一个类型:懒汉模式饿汉模式*/饿汉模式publicclassSingleton{//1... 查看详情

java:java学习笔记之synchronized的简单理解和使用(代码片段)

JavaSynchronized的简单理解和使用Synchronized0、背景1、synchronized锁是什么?2、特点3、优点4、使用场景4.1.修饰实例方法:4.2.修饰静态方法:4.3.修饰代码块:4.4、注意4.5、双重校验锁实现对象单例(线程安全)4.6、总结5、底... 查看详情

java设计模式之二-----工厂模式

在上一篇中我们学习了单例模式,介绍了单例模式创建的几种方法以及最优的方法。本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式、工厂方法和抽象工厂模式。简单工厂模式简单工厂模式是属于创建型模式,又叫做... 查看详情

设计模式:学习笔记——单例模式

Java设计模式之单例模式引入单例模式什么是单例模式  对于某些类来说,我们只想其拥有一个实例,并且我们仅仅使用这一个实例:比如说线程池,缓存,对话框,处理偏好设置和注册表的对象、日志对象、显卡等设备的驱... 查看详情

java进阶篇设计模式之二-----工厂模式

前言在上一篇中我们学习了单例模式,介绍了单例模式创建的几种方法以及最优的方法。本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式、工厂方法和抽象工厂模式。简单工厂模式简单工厂模式是属于创建型模式,又... 查看详情

《java与模式》学习笔记——singleton

单例(Singleton)模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。一些资源管理器常常设计成单例模式。 单例模式的结构如下:... 查看详情

java设计模式之单例学习与掌握(代码片段)

文章目录定义特点优缺点应用场景实现懒汉式单例饿汉式单例单例模式的扩展定义某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。特点单例类只有一个实例对象;该... 查看详情

java单例模式之双检锁深入思考

...延迟加载的模式,一种是非延迟加载的模式,今天我们来学习一下基于双检锁延迟加载的单例模式。###什么是单例模式顾名思义,单例模式指的是在整个程序运行期间,我们只能初始化某个类一次,然后一直使用 查看详情

java单例模式之学习

经典的单例模式:   publicclassSingleton   privatestaticSingletonuniqueInstance=null;   privateSingleton()     //Existsonlytodefeatinstantiation.      publicstaticSingletongetInstance()     if(uniqueInstance==null)      uniqueInstance=newSin... 查看详情

java学习笔记之面向对象

...种编程思想,强调对象,是一种思考问题的思维模式。在学习面向对象的时候,我们要建立起自己面向对象的思维模式。(1)、先整体,后局部。(2)、先抽象,后具体。(3)、能做什么,再怎么做。2、面向对象具有什么特... 查看详情

java学习笔记——设计模式之七.模板方法模式

模板方法模式(TemplateMethod),定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。结构图:代码:算法骨架:1packagecn.happy.design_pattern._0... 查看详情

java笔记之静态修饰附和单例设计模式

                           第六天笔记静态修饰符static:一.static修饰成员变量:static 查看详情

java设计模式之单例(singleton)模式

1. 单例模式的定义       单例模式(SingletonPattern)是一个比较简单的模式,其原始定义如下:Ensureaclasshasonlyoneinstance,andprovideaglobalpointofaccesstoit. 即确保只有一个实例,而且自行实例化并向整个系... 查看详情

java设计模式之单例模式_懒汉式

单例模式 初识:单例模式(SingletonPattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有... 查看详情

java设计模式之单例模式你真的会了吗?(饿汉式篇)

java设计模式之单例模式你真的会了吗?(饿汉式篇)java设计模式之单例模式你真的会了吗?(饿汉式篇)一、什么是单例模式?单例模式(SingletonPattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,... 查看详情

java单例模式之总有你想不到的知识

文章目录Java单例模式单例模式是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式单例模式确保在一个应用程序中某一个类只有一个实例,而且自行实例化并向整个系统提供... 查看详情

java设计模式之单例模式

一、概述单例模式的定义就是确保某一个类只有一个实例,并且提供一个全局访问点。属于设计模式三大类中的创建型模式。单例模式具有典型的三个特点:只有一个实例。自我实例化。提供全局访问点。其UML结构图非常简单,... 查看详情