设计模式之单例模式

1.单例模式概念

保证一个类只有一个实例,并提供一个全局访问点

2.单例模式的几种模式

1)饿汉式单例模式

static在类的加载时,就创建了对象,线程是安全的

2)懒汉式线程不安全单例模式

使用方法创建单例,但是在多线程下是不安全的,(两个或多个线程同时获取单例,并且实例还没有创建)

3)懒汉式线程安全单例模式

使用方法创建单例,并且在方法上加上synchronized锁(把这个方法锁住了,想要访问这个的单例时候需要等别的线程使用完毕)

3.懒汉式与饿汉式的区别

懒汉式在类加载时就已经创建了对象实例,饿汉式在第一次方法调用时才加载

4.懒汉式线程安全与线程不安的区别

在方法上加上synchronized锁,其他线程在使用的时候就需要等待正在使用线程使用完毕才行.

(举个栗子:当你上厕所时,忘记锁门了,来了一个着急上厕所的,看见没有锁,也不知道你在使用,可能就闯进去了)

5.代码实现

1)普通类Singer

java 复制代码
package org.xiji.single;

/**
 * 普通类
 */
public class Singer {
}

2)饿汉式单例类SingleEager

java 复制代码
package org.xiji.single;

/**
 * 饿汉式
 */
public class SingleEager {
    /**
     * 静态变量 类加载时就已经创建,并且只创建一次,所以是线程安全的
     */
    private static SingleEager singleEager = new SingleEager();

    /**
     * 获取单例
     */
    public static SingleEager getSingleEager(){
        return singleEager;
    }
}

3)懒汉式单例模式线程不安全SingleLazyUnSafe

java 复制代码
package org.xiji.single;

/**
 * 单例模式,线程不安全
 */
public class SingleLazyUnSafe {

    private static SingleLazyUnSafe instance;

    /**
     * 获取实例
     */
    public static SingleLazyUnSafe getInstance(){
        //如果 实例为空,则创建实例
        if (instance == null) {
            return new SingleLazyUnSafe();
        }
        //实例不为空,返回实例
        return instance;
    }
}

4)懒汉式单例模式线程安全

java 复制代码
package org.xiji.single;

/**
 * 线程安全
 */
public class SingleLazySafe {
    // 使用锁 保证线程安全
    private static SingleLazySafe singleLazySafe; //定义单例对象

    /**
     * 这个相对于线程不安全的区别就是加锁了 多了一个synchronized
     *
     */
    public static synchronized SingleLazySafe getInstance(){
        if(singleLazySafe == null){
            singleLazySafe = new SingleLazySafe();
        }
        return singleLazySafe;
    }
}

SingleMain类

java 复制代码
package org.xiji.single;

/**
 * 单例模式
 */
public class SingleMain {
    public static void main(String[] args) {

        /**
         * 创建普通对象
         */
        Singer singer = new Singer();
        Singer singer1 = new Singer();
        System.out.println("普通对象是否相等" +singer.equals(singer1));
        //肯定是不相等的
        System.out.println("==================================================");
        /**
         * 通过饿汉式单例模式创建
         */
        SingleEager singleEager = SingleEager.getSingleEager();
        SingleEager singleEager1 = SingleEager.getSingleEager();

        System.out.println("单例模式对象是否相等" +singleEager.equals(singleEager1));
        //肯定是相等的
        System.out.println("==================================================");

        /**
         *  通过懒汉式线程安全的单例模式创建  + synchronized锁
         */
        SingleLazySafe singleLazySafe = SingleLazySafe.getInstance();

        /**
         * 通过懒汉式线程不安全的单例模式创建  不加 synchronized锁
         */
        SingleLazyUnSafe singleLazyUnSafe = SingleLazyUnSafe.getInstance();
    }
}

5)运行结果

相关推荐
x-cmd21 分钟前
[x-cmd] 终端里的飞书:lark-cli,让 AI Agent 拥有“实体办公”能力
java·人工智能·ai·飞书·agent·x-cmd
吾日三省Java36 分钟前
SpringBoot锁设计:让你的系统不再“抢”出问题!
java·spring boot·设计思路
XXOOXRT41 分钟前
Ubuntu搭建Java项目运行环境(JDK17+MySQL8.0)超详细教程
java·linux·mysql·ubuntu
m0_7190841142 分钟前
启动命令111
java
客卿1231 小时前
用两个栈实现队列
android·java·开发语言
java1234_小锋1 小时前
Java高频面试题:谈谈你对SpringBoot的理解?
java·开发语言·spring boot
空空潍1 小时前
Spring AI 实战系列(三):多模型共存+双版本流式输出
java·人工智能·spring
彭于晏Yan1 小时前
SpringBoot整合ECC实现文件签名与验签
java·spring boot·后端
pupudawang1 小时前
Spring EL 表达式的简单介绍和使用
java·后端·spring
jiankeljx1 小时前
Spring Initializr创建springboot项目,提示java 错误 无效的源发行版:16
java·spring boot·spring