【算法题】单例模式的8种实现方式(java版)「建议收藏」

【算法题】单例模式的8种实现方式(java版)「建议收藏」根据马士兵老师的视频整理下来的8种单例模式的实现方式,在此记录一下。代码示例1:饿汉式packagecom.examples.singleton;publicclassMgr01{publicstaticvoidmain(String[]args){Mgr01m1=Mgr01.getInstance();Mgr01m2=Mgr01.getInstance();System.out.println(m1…

大家好,又见面了,我是你们的朋友全栈君。

根据马士兵老师的视频整理下来的8种单例模式的实现方式,在此记录一下。

代码示例1:饿汉式

package com.examples.singleton;

public class Mgr01 {
    public static void main(String[] args) {
        Mgr01 m1 = Mgr01.getInstance();
        Mgr01 m2 = Mgr01.getInstance();
        System.out.println(m1==m2);
    }

    //class文件加载时进行类的实例化
    private static Mgr01 INSTANCE = new Mgr01();
    //构造方法私有化
    private Mgr01(){};
    public static Mgr01 getInstance(){return INSTANCE;}
    public void m(){ System.out.println("Mgr01"); }
}

说明:

以上是饿汉式单例,就是在类加载的时候完成实例化,而且只有一个实例;同时JVM能够保证线程安全,简单实用,推荐使用。

缺点:不管是否用到,类装载的时候就已经完成了实例化

代码示例2:和示例1类似,只不过将实例化在静态代码块中完成

package com.examples.singleton;


public class Mgr02 {
    public static void main(String[] args) {
        Mgr02 m1 = Mgr02.getInstance();
        Mgr02 m2 = Mgr02.getInstance();
        System.out.println(m1==m2);
    }

    //class文件加载时进行类的实例化
    private static Mgr02 INSTANCE ;
    static {

        INSTANCE = new Mgr02();
    }

    //构造方法私有化
    private Mgr02(){};
    public static Mgr02 getInstance(){return INSTANCE;}
    public void m(){ System.out.println("Mgr01"); }

}

代码示例3:懒汉式

package com.examples.singleton;


public class Mgr03 {
    public static void main(String[] args) {
        for(int i=0;i<50;i++) {
            new Thread(()->{
               System.out.println(Mgr03.getInstance().hashCode());
            }).start();
        }
    }

    private static Mgr03 INSTANCE ;
    //构造方法私有化
    private Mgr03(){};
    public static Mgr03 getInstance(){
        if(INSTANCE==null){
            try{
                Thread.sleep(1);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            INSTANCE = new Mgr03();
        }
        return INSTANCE;
    }
    public void m(){ System.out.println("Mgr01"); }
}

多线程执行结果:

【算法题】单例模式的8种实现方式(java版)「建议收藏」

说明:为了解决不管是否使用都会实例化的问题,但是却带来线程不安全的问题

代码示例4:懒汉式+锁

package com.examples.singleton;


public class Mgr03 {
    public static void main(String[] args) {
        for(int i=0;i<50;i++) {
            new Thread(()->{
                System.out.println(Mgr03.getInstance().hashCode());
           }).start();
        }
    }

    private static Mgr03 INSTANCE ;
    //构造方法私有化
    private Mgr03(){};
    public static synchronized Mgr03 getInstance(){
        if(INSTANCE==null){
            try{
                Thread.sleep(1);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            INSTANCE = new Mgr03();
        }
       return INSTANCE;
    }
    public void m(){ System.out.println("Mgr01"); }
}

说明: 通过给getInstance()方法加锁,解决对象不唯一的问题,但是同时也带来效率下降的问题

代码示例5:懒汉式+锁+减少同步代码块

package com.examples.singleton;


public class Mgr05 {
    public static void main(String[] args) {
        for(int i=0;i<50;i++) {
            new Thread(()->{
                System.out.println(Mgr05.getInstance().hashCode());
            }).start();
        }
    }

    private static Mgr05 INSTANCE ;
    private Mgr05(){};
    public static  Mgr05 getInstance(){
        if(INSTANCE==null){
            //试图通过减小同步代码块的方式提高效率,但是并不可行
            synchronized(Mgr05.class){
                try{
                    Thread.sleep(1);
                }catch (InterruptedException e){
                   e.printStackTrace();
                }
                INSTANCE = new Mgr05();
            }
        }
        return INSTANCE;
    }
    public void m(){ System.out.println("Mgr01"); }

}

多线程执行结果:

【算法题】单例模式的8种实现方式(java版)「建议收藏」

说明:同样存在线程不安全的问题,因为第一个if判断条件有可能导致在对象没有实例化之前,不同的线程进入到if代码块中,拿到锁之后进行实例化

代码示例6:懒汉式+锁+双重检查

package com.examples.singleton;


public class Mgr06 {
    public static void main(String[] args) {
        for(int i=0;i<50;i++) {
            new Thread(()->{
                System.out.println(Mgr06.getInstance().hashCode());
            }).start();
        }
    }

    private static Mgr06 INSTANCE ;
    private Mgr06(){};
    public static Mgr06 getInstance(){
        if(INSTANCE==null){
            //双重检查
            synchronized(Mgr06.class){
                if(INSTANCE==null) {
                    try{
                        Thread.sleep(1);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    INSTANCE = new Mgr06();
                }
            }
        }
        return INSTANCE;
    }
    public void m(){ System.out.println("Mgr01"); }
}

可以保证线程安全

代码示例7:静态内部类

package com.examples.singleton;


public class Mgr07 {
    public static void main(String[] args) {
        for(int i=0;i<50;i++) {
            new Thread(()->{
                System.out.println(Mgr07.getInstance().hashCode());
            }).start();
        }
    }
    private static  class Mgr07Holder{
        private final static Mgr07 INSTANCE = new Mgr07();
    }
    private Mgr07(){};
    public static Mgr07 getInstance(){
        return Mgr07Holder.INSTANCE;
    }
    public void m(){ System.out.println("Mgr01"); }
}

说明:加载外部类时不会加载内部类,这样可以实现懒加载,JVM保证线程安全,类只加载一次

代码示例8:枚举类

package com.examples.singleton;


public enum Mgr08 {
    INSTANCE;
    public void m(){ System.out.println("Mgr08"); }
    public static void main(String[] args) {
        for(int i=0;i<50;i++) {
            new Thread(()->{
                System.out.println(Mgr08.INSTANCE.hashCode());
            }).start();
        }
    }
}

说明:以上方法不单能实现单例,而且能防止被反序列化,因为枚举类没有构造方法,所以即使得到了class文件也不能被反序列化。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/156766.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月8日 下午10:36
下一篇 2022年7月8日 下午10:46


相关推荐

  • java实现无锁队列

    java实现无锁队列okimportjava util Random importjava util concurrent ExecutorServ importjava util concurrent Executors importjava util concurrent TimeUnit importjava util concurrent atomic AtomicIntege importjava util concurrent atomic AtomicRefere

    2026年3月18日
    2
  • go语言环境安装教程_go语言菜鸟教程

    go语言环境安装教程_go语言菜鸟教程windows下go语言环境搭建安装1、go安装包下载:https://studygolang.com/dl选择自己要下载的版本进行下载。下载好了之后安装一直next就行了(安装路径尽量不要出现中文。)2、安装好了之后打开cmd,输入goversion查一下是否安装成功。出现go版本号,说明安装成功。3、下载liteidehttps://sourceforge.net/pro…

    2022年10月12日
    4
  • vue父子组件传值props_vue子组件调用父组件的方法并传参

    vue父子组件传值props_vue子组件调用父组件的方法并传参vue页面结构在做项目的时候常常有这样的一个情况,这个页面的数据(比如:id号)要带到另一个页面去查询某个数据的详情等,传统的做法不是在url上加参数,cookie或者是现在H5的“sessionStorage”和“localStorage”上赋值,这是页面之间传递的方法。随着Angularjs,React,Vue的流行组件式的开发方式成为另一种不错的解决方案。最近就有一些小伙伴问我,vue组件之间是如何传递参数的?其实vue是有三种方式可以组件之间传递数据(props,组件通信,slot)..

    2025年6月24日
    5
  • idea2021.7.20激活码-激活码分享

    (idea2021.7.20激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlMLZPB5EL5Q-eyJsaWNlbnNlSW…

    2022年3月21日
    121
  • 用AVX2指令集优化浮点数组求和

    用AVX2指令集优化浮点数组求和用AVX2指令集优化浮点数组求和一、AVX2指令集介绍二、代码实现0.数据生成1.普通数组求和2.AVX2指令集求和:单精度浮点(float)3.AVX2指令集求和:双精度浮点(double)三、性能测试测试环境计时方式测试内容进行性能测试第一次测试第二次测试四、总结个人猜测原因:一、AVX2指令集介绍AVX2是SIMD(单指令多数据流)指令集,支持在一个指令周期内同时对256位内存进行操作。包含乘法,加法,位运算等功能。下附Intel官网使用文档。Intel®IntrinsicsGuid

    2022年5月7日
    51
  • ICMP详解「建议收藏」

    ICMP详解「建议收藏」ICMP(InternetControlMessageProtocol)网际控制报文协议。它是TCP/IP协议簇的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。ICMP使用IP的基本支持,就像它是一个更高级别的协议,但是,ICMP实际上是IP的…

    2022年7月12日
    22

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号