Java实现单例模式的五种方法介绍

5种Java实现单例模式的方法介绍

在Java编程中,当我们希望某个类只有一个实例存在时,就需要使用单例模式。下面介绍5种Java实现单例模式的方法:

方法1:饿汉式单例模式

这种方式基于classloder机制避免了多线程的同步问题,不过instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法,但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。

示例:

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

方法2:懒汉式单例模式(线程不安全)

这种方法实现起来很简单,只需要在第一次调用的时候实例化对象即可,但是在多线程下是不安全的。

示例:

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

方法3:懒汉式单例模式(线程安全,效率低)

这种方法考虑到了线程安全,但是效率很低,因为整个方法被synchronized所修饰,因此每次调用getInstance时都要对对象加锁,试图通过减小锁的范围提高效率,结果往往会出现错误或不可靠的情况。

示例:

public class Singleton3 {
    private static Singleton3 instance;
    private Singleton3(){}
    public static synchronized Singleton3 getInstance(){ //加锁
        if(instance == null){
            instance = new Singleton3();
        }
        return instance;
    }
}

方法4:双检锁/双重校验锁(DCL,即double-checked locking)

这种方法致力于解决懒汉式单例模式(线程安全,效率低)的效率问题,只有在第一次创建对象的时候才会加锁,达到了又能解决线程安全问题,又能提高效率的目的。

示例:

public class Singleton4 {
    private volatile static Singleton4 instance;// volatile:禁止指令重排序
    private Singleton4(){}
    public static Singleton4 getInstance(){
        if(instance == null){
            synchronized (Singleton4.class){  //加锁
                if(instance == null){
                    instance = new Singleton4();
                }
            }
        }
        return instance;
    }
}

方法5:静态内部类单例模式

这种方法也是懒汉式单例模式的一种形式,但是相对于其他方法而言更为安全高效。当Singleton5类被载入JVM时,其内部类SingletonHolder并不会被初始化。只有当调用getInstance方法时,才会加载SingletonHolder类,从而实例化Singleton5。同时,由于SingletonHolder是静态的,所以JVM不会重新加载。

示例:

public class Singleton5 {
    private Singleton5(){}
    private static class SingletonHolder{
        private static final Singleton5 INSTANCE = new Singleton5();
    }
    public static Singleton5 getInstance(){
        return SingletonHolder.INSTANCE;
    }
}

以上5种方法各有优缺点,根据不同的情况选择合适的单例模式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现单例模式的五种方法介绍 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • SpringBoot进行参数校验的方法详解

    SpringBoot进行参数校验的方法详解 一、为什么需要参数校验? 在实际开发中,我们常常需要对一些参数进行校验,防止参数不合法导致程序出错。比如在登录界面中,用户名和密码不能为空,当用户输入的用户名密码为空时,我们需要提示用户输入正确的用户名和密码。如果没有对参数进行校验,程序会直接抛出空指针异常,这是非常不可取的。 二、SpringBoot参数校验的方…

    Java 2023年5月19日
    00
  • java类实现日期的时间差的实例讲解

    Java 类实现日期的时间差的实例讲解 在Java中,我们可以通过使用Java类库提供的Date和Calendar类来处理日期和时间。这些类提供了一些方法,可以用于计算两个日期之间的时间差。 使用Date类实现日期的时间差 以下是使用Date类实现日期的时间差的示例代码: package com.example.date; import java.util.…

    Java 2023年5月20日
    00
  • Java编码辅助工具Lombok用法详解

    Java编码辅助工具Lombok用法详解 Lombok是一个Java编码辅助工具,可以简化Java代码的编写。下面将详细讲解Lombok的用法。 安装 Lombok可以在Maven中央仓库中获取。在Maven项目中引入Lombok的依赖即可: <dependency> <groupId>org.projectlombok</gr…

    Java 2023年5月20日
    00
  • Java for循环和foreach循环的性能对比分析

    Java for循环和foreach循环的性能对比分析 1. 前言 循环是程序中必不可少的一部分,Java中常用的两种循环方式为for循环和foreach循环。本篇文章将对这两种循环方式的性能进行对比分析。 2. for循环与foreach循环 2.1 for循环 for循环是一种基于计数器的循环结构,通常用于循环次数已知的情况。for循环的语法如下: fo…

    Java 2023年5月26日
    00
  • 教你如何轻松学会Java快慢指针法

    教你如何轻松学会Java快慢指针法 概述 快慢指针法又叫双指针法,它是一种简单的算法,其核心思想依靠两个指针,一个快指针,一个慢指针来解决问题。在Java中的应用非常广泛,在链表、数组、字符串、树等数据结构中均能见到它的身影。它的时间复杂度通常是O(n),能极大的提高算法效率。 原理 快慢指针法的核心是两个指针,一个快指针,一个慢指针,它们的运动速度一般不同…

    Java 2023年5月26日
    00
  • Tomcat配置及如何在Eclipse中启动

    下面我将详细讲解Tomcat配置及如何在Eclipse中启动的完整攻略。 1. Tomcat配置 Tomcat是开源的Web应用程序服务器,它可以为使用Java Servlet和JSP的Web应用程序提供运行环境。在使用Tomcat之前,需要进行配置。 1.1 下载Tomcat 首先需要在Tomcat官网下载Tomcat安装包,下载地址为http://tom…

    Java 2023年5月19日
    00
  • Java Spring中Bean的作用域及生命周期

    当我们在使用Java Spring框架的时候,经常会听到Bean这个词。Bean是Java Spring框架中的一个基础概念,每一个Bean实际上就是一个Java对象。在Spring中,Bean有不同的生命周期和作用域,这些都是我们必须了解的。 1. Bean的生命周期 Bean的生命周期主要分为三个部分:实例化、初始化和销毁。 1.1 实例化 在Sprin…

    Java 2023年5月19日
    00
  • struts2 action跳转调用另一个程序

    下面是详细讲解“struts2 action跳转调用另一个程序”的完整攻略。 1. 背景 在实际应用中,我们经常需要在一个操作完成后,跳转到另一个程序执行相应的操作。这时候,就需要在struts2 action中进行页面跳转,并调用另一个程序。下面我们来讲解具体的实现步骤。 2. 实现步骤 2.1 页面跳转 首先,在struts2 action中进行页面跳转…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部