设计模式之单例模式

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)运行结果

相关推荐
叫我阿柒啊21 分钟前
Java全栈开发实战:从基础到微服务的深度解析
java·微服务·kafka·vue3·springboot·jwt·前端开发
凯尔萨厮38 分钟前
Java学习笔记三(封装)
java·笔记·学习
霸道流氓气质38 分钟前
Java开发中常用CollectionUtils方式,以及Spring中CollectionUtils常用方法示例
java·spring
失散1340 分钟前
分布式专题——5 大厂Redis高并发缓存架构实战与性能优化
java·redis·分布式·缓存·架构
通达的K40 分钟前
Java实战项目演示代码及流的使用
java·开发语言·windows
David爱编程1 小时前
深入 Java synchronized 底层:字节码解析与 MonitorEnter 原理全揭秘
java·后端
索迪迈科技1 小时前
Protobuf 新版“调试表示为什么有链接?为什么会打码?我该怎么改代码?
java·log4j·apache
a_blue_ice1 小时前
JAVA 面试 MySQL
java·mysql·面试
月阳羊2 小时前
【硬件-笔试面试题-76】硬件/电子工程师,笔试面试题(知识点:H桥驱动电路的设计要点)
java·单片机·嵌入式硬件·面试·职场和发展
赵星星5202 小时前
MySQL的默认隔离级别:为什么是可重复读(RR)而非读已提交(RC)?
java