当前位置: 首页 > news >正文

Java 23种设计模式 之单例模式 7种实现方式

一、懒汉式(线程不安全)

package com.java.singleton;

//懒汉式 线程不安全
public class LazySingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private LazySingleton() {
    }


    private static LazySingleton instance = null;

    //创建实例
    public static LazySingleton getInstance() {

        if (instance == null) {
            instance = new LazySingleton();
        }

        return instance;
    }
}

二、懒汉式(线程安全)

package com.java.singleton;

//懒汉式 线程安全
public class SynchronizedLazySingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private SynchronizedLazySingleton() {
    }


    private static SynchronizedLazySingleton instance = null;

    //创建实例  线程安全
    public static synchronized SynchronizedLazySingleton getInstance() {

        if (instance == null) {
            instance = new SynchronizedLazySingleton();
        }

        return instance;
    }

}

三、饿汉式(线程安全)

package com.java.singleton;

//饿汉式
public class HungrySingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private HungrySingleton() {
    }

    //静态初始化 由JVM保证线程安全
    private static HungrySingleton instance = new HungrySingleton();

    //创建实例
    public static HungrySingleton getInstance() {

        return instance;
    }

}

四、缓存实现(线程不安全)

package com.java.singleton;

import java.util.HashMap;
import java.util.Map;

//线程不安全 缓存实现
public class CacheSingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private CacheSingleton() {
    }

    //构造缓存容器
    private static Map<String, CacheSingleton> map = new HashMap<>();

    //构造默认的存放key
    private static final String DEFAULT_KEY = "Cache";


    //创建实例
    public static CacheSingleton getInstance() {

        //先从缓存中取 没有就创建并放入缓存  有就返回
        CacheSingleton instance = (CacheSingleton) map.get(DEFAULT_KEY);

        if (instance == null) {

            instance = new CacheSingleton();
            map.put(DEFAULT_KEY, instance);
        }

        return instance;
    }

}

五、双重检查加锁(懒汉式 线程安全的进一步优化)

package com.java.singleton;


//双重检查加锁  懒汉式在方法上加synchronized的进一步优化
public class DoubleCheckedLockingSingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private DoubleCheckedLockingSingleton() {
    }

    //volatile 修饰的变量不会被本地线程缓存 对该变量的读写直接作用于共享内存 类似于互斥锁
    private volatile static DoubleCheckedLockingSingleton instance = null;

    //创建实例
    public static DoubleCheckedLockingSingleton getInstance() {

        if (instance == null) {

            synchronized (DoubleCheckedLockingSingleton.class) {

                if (instance == null) {
                    instance = new DoubleCheckedLockingSingleton();
                }
            }

        }

        return instance;
    }


}

六、 Lazy Initialization Holder Class实现单例

package com.java.singleton;


//静态内部类 Lazy Initialization Holder Class
public class LazyInitializationHolderClassSingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private LazyInitializationHolderClassSingleton() {
    }

    /*
     * 静态成员式内部类 该内部类的实例对象与外部类的实例无绑定关系
     * 有且只有在LazyInitializationHolder被调用instance时 在会对对象实例进行装载
     * 从而实现延时加载
     */
    private static class LazyInitializationHolder {

        /*
         * 静态初始化器 由JVM保证线程安全
         *
         */
        private static LazyInitializationHolderClassSingleton instance = new LazyInitializationHolderClassSingleton();
    }


    //创建实例
    public static LazyInitializationHolderClassSingleton getInstance() {

        return LazyInitializationHolder.instance;
    }


}

七、枚举实现单例

package com.java.singleton;

public enum EnumSingleton {

    //枚举类的每个元素 都代表一个单例
    uniqueEnumSingleton;


    public  void method() {

        System.out.println("EnumSingleton"+uniqueEnumSingleton.hashCode());
    }

}

八、测试类

package com.java.singleton;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SingletonApplicationTests {

    @Test
    public void testCacheSingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("CacheSingleton\t" + CacheSingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }

    @Test
    public void testDoubleCheckedLockingSingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("DoubleCheckedLockingSingleton\t" + DoubleCheckedLockingSingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }

    @Test
    public void testEnumSingleton() {

        for (int i = 0; i < 3; i++) {

            EnumSingleton.uniqueEnumSingleton.method();
        }
        System.out.println("-------------------------------------------------------------------\n");
    }


    @Test
    public void testHungrySingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("HungrySingleton\t" + HungrySingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }


    @Test
    public void testLazyInitializationHolderClassSingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("LazyInitializationHolderClassSingleton\t" + LazyInitializationHolderClassSingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }

    @Test
    public void testLazySingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("LazySingleton\t" + LazySingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }


    @Test
    public void testSynchronizedLazySingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("SynchronizedLazySingleton\t" + SynchronizedLazySingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }


}

九、测试结果
图片描述

相关文章:

  • webpack.config.js====图片处理
  • 军武科技获5000万元B轮融资 男性用户占比达到90%以上
  • ASP.NET Core 3.0项目开始“瘦身”
  • JavaScript 判断 iPhone X Series 机型
  • 学习HTTP相关知识笔记
  • 报错 could not find php_pdo或者driver
  • 智慧出行加持广西春运 科技让回家变得简单从容
  • 计算性能提升100倍,Uber推出机器学习可视化调试工具
  • 用垃圾回收机制解释JavaScript中的闭包
  • 阿里云Kubernetes容器服务上体验Knative
  • 用编码器-解码器-重构器框架实现英语-日语的神经机器翻译
  • netty-客户端.channel()方法 源码分析.md
  • Java 多线程编程之:notify 和 wait 用法
  • django之配置静态文件
  • 区块链多币种测试网络钱包(开源)
  • SegmentFault for Android 3.0 发布
  • axios 和 cookie 的那些事
  • chrome扩展demo1-小时钟
  • ES6 ...操作符
  • gitlab-ci配置详解(一)
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • js 实现textarea输入字数提示
  • MySQL几个简单SQL的优化
  • PV统计优化设计
  • Python学习笔记 字符串拼接
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 高程读书笔记 第六章 面向对象程序设计
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 使用 QuickBI 搭建酷炫可视化分析
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 学习使用ExpressJS 4.0中的新Router
  • 一道面试题引发的“血案”
  • 一个JAVA程序员成长之路分享
  • 硬币翻转问题,区间操作
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​如何防止网络攻击?
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #define
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (MATLAB)第五章-矩阵运算
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (十六)一篇文章学会Java的常用API
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)Linux下编译安装log4cxx
  • .NET Framework 4.6.2改进了WPF和安全性
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .Net mvc总结
  • .Net Web项目创建比较不错的参考文章
  • .NET 常见的偏门问题
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded