Java单例模式7种写法,你是不是有用错过?

公众号:码农乐园 等级 461 0 0

单例大家都很清楚的知道作用,也不多说,主要是在不同的情况下注意事项;

单例模式多种写法 1、饿汉式[可用] //饿汉式

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

优点:这种单例写法比较简单,就是在类加载的时候就完成实例化。静态避免了线程同步问题。

缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。

2、饿汉式[可用]

  static  Singleton singleton;
static {
     singleton = new Singleton();
}
public static  Singleton  getInstance1(){
    return singleton;
}

这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。优缺点和上面是一样的。

3、懒汉式[不可用]

  static  Singleton singleton;
public static Singleton getInstance2() {
    if (singleton == null) {
        singleton = new Singleton();
    }
    return singleton;
}

如果在多线程下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可使用这种方式。

4、懒汉式[不推荐用]

//懒汉式线程安全

  static  Singleton singleton;
public static synchronized Singleton getInstance3(){
    if (singleton == null){
        singleton = new Singleton();
    }
    return singleton;
}

解决上面第三种实现方式的线程不安全问题,做个线程同步就可以了,getInstance()方法进行了线程同步。

缺点:效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低要改进。

5、懒汉式[不可用]

  static  Singleton singleton;
public static Singleton getInstance4() {
    if (singleton == null) {
        synchronized (Singleton.class) {
            singleton = new Singleton();
        }
    }
    return singleton;
}

由于第四种实现方式同步效率太低,所以摒弃同步方法,改为同步产生实例化的的代码块。但是这种同步并不能起到线程同步的作用。跟第3种实现方式遇到的情形一致,假如一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。

6、双重检查[推荐用]

  static  Singleton singleton;
public static  Singleton getInstance5(){
    if (singleton == null){
        synchronized (Singleton.class){
            if (singleton == null){
                singleton = new Singleton();
            }
        }
    }
    return singleton;
}

Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,我们进行了两次if (singleton == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if (singleton == null),直接return实例化对象。

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

7、静态内部类[推荐用]

  public static class SingletonInstance{
    private static final  Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance6(){
    return SingletonInstance.INSTANCE;
}

优点:这种写法避免了线程不安全,延迟加载,效率高。

优点 系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。

缺点 当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new,可能会给其他开发人员造成困扰,特别是看不到源码的时候。

收藏
评论区

相关推荐

通过一个简单实例了解vuex
简单说明 什么是vuex,vuex怎么使用,什么场景下适合使用vuex, vuex 文档(https://links.jianshu.com/go?tohttps%3A%2F%2Fvuex.vuejs.org%2Fzh%2F)中都有介绍。看完文档之后,都知道vuex的核心有State、Getter、Mutation、Action、Modul
项目实战,动态增删form表单
前言 Hi,大家好,我是麦叔。今天老大让我做一个需求,我们的这个表单以前只支持录入一个检查器具。现在要求改为可以动态添加,满足录入多个器具。作为前
Java单例模式7种写法,你是不是有用错过?
单例大家都很清楚的知道作用,也不多说,主要是在不同的情况下注意事项; 单例模式多种写法 1、饿汉式可用 //饿汉式 language private final static Singleton INSTANCE new Singleton(); private Singleton(){} public static Singleton
创建型模式之单例设计模式
什么是单例设计模式? 顾名思义,只有一个实例。 单例模式它主要是确保一个类只有一个实例,并且可以提供一个全局的访问点。 废话少说,直接上干货了 单例模式之饿汉式 所谓饿汉式,顾名思义,“ 它很饿 ”。所以说,它一旦被加载进来,就会直接实例化一个对象。 例如: language class Singleton { private static fin
《java 核心技术》卷1 学习 概述 第一章Java程序设计概述
从浅面了解Java 1.Java 在语言得地位 现在有所下降 但仍是老大哥 所以值得学习 2.Java特性 1.简单性:从一方面来说 Java可以支持在小型机器上运行 必定不是很复杂得,所以上手不难 2.面向对象:Java有相比于其他的语言 更简单得接口
c++11 实现单例模式
C11出来后,里面新增加了好多好用的功能 下面的单例就是使用了C11中的标准库中的mutex和unique_prt 进行内存管理的. 此单例模式不用担心内存的释放问题 pragma once include <memory include <mutex template <class T class Singleton { public: ty
Spring Cloud OAuth2 微服务认证授权
OAuth 2.0 是用于授权的行业标准协议,它致力于简化客户端开发人员的工作,同时为 Web 应用、桌面应用、移动应用等各种客户端应用提供了特定的授权流程。本文讲解如何使用 OAuth2 协议来授权客户端应用访问 Spring Cloud 微服务。 微服务认证授权概述 单点登录 相比于单体应用,微服务应用需要在多个服务之间共享
JavaScript设计模式之单例模式
<section id"nice" datatool"mdnice编辑器" datawebsite"https://www.mdnice.com" style"fontsize: 16px; color: black; lineheight: 1.6; wordspacing: 0px; letterspacing: 0px; word
java IO编程实例——投票选举
(1)功能描述有一个半采用民主投票的方法推选班长,班长候选人共4位,每个人姓名以及代号分别为“张三 1,李四 2,王五 3,赵六 4”。程序操作员将每张选票上所填的代号(1、2、3、4)循环输入电脑,输入数字0结束输,然后将所有候选人的得分情况显示出来,并显示最终当选者结果。(2)具体要求要求用面向对象方法,编写学生类Student,将候选人姓名、代号与票数
java IO编程实例——文件内容复制
题目:完成文件内容复制操作,在程序运行后提示输入源文件路径,然后再输入目标文件路径。 package person.xsc.praticeIII;import java.io. ;import java.util.Scanner;public class Copy public static void main(String args[]) throws I
【单例深思】饿汉式
1、抛出问题1. 为什么饿汉式单例是线程安全的?2. 为什么饿汉式单例没有延迟加载(Lazy Loading)? 2、JVM类加载机制饿汉式单例的实现:javapublic class Singleton private static Singleton singleton new Singleton(); private S
2021年度最全面JVM虚拟机,类加载过程与类加载器
前言类装载器子系统是JVM中非常重要的部分,是学习JVM绕不开的一关。一般来说,Java 类的虚拟机使用 Java 方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。每个这样的实例用来表
一篇文章通俗易懂的让你彻底理解 Java 注解
很多Java程序员,对Java的注解一知半解,更有甚者,有的人可能连注解是什么都不知道本文我们用最简单的 demo , 最通俗最短的语言,带你了解注解到底是什么?先来简单回顾一下基础,我们知道,Java 的源文件编辑后,生成 .class 文件,1. .Java源文件,这个是源文件时期2. 源文件经过编译生成 .class 字节码文件,这个也是编译时期3
2021年度最全面JVM虚拟机,类加载过程与类加载器
前言类装载器子系统是JVM中非常重要的部分,是学习JVM绕不开的一关。一般来说,Java 类的虚拟机使用 Java 方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。每个这样的实例用来表
Python基础7——单例模式
15 单例模式 15.1 init和new方法执行步骤1. 实例化一个对象,先执行new方法,在new方法中返回对象2. 然后再调用init方法 15.1.1 \\init\\方法init 是构造方法<font color"red"其实最先调用的方法是new方法</font,但是大部分情况下是不使用new方法pythonclass Test(object):