剑指offer-面试题2:实现单例模式

本文详细介绍了Java中的单例模式,包括饿汉式、懒汉式、懒汉式线程安全、双重校验锁(DCL)、静态内部类和枚举类等六种实现方式,并通过测试代码展示了它们在多线程环境下的表现。同时,文章还讨论了线程安全和性能之间的权衡,为读者深入理解单例模式提供了全面的视角。
摘要由CSDN通过智能技术生成

单例模式即一个类只有一个实例,并实现该实例的全局访问点

1.饿汉式

直接实例化,比如打开淘宝首页,会看到所有文字和图片都显示出来

实现代码:

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

2.懒汉式

懒汉式可以延迟实例化,比如某些网站打开只看到图片的轮廓,过一会才能看到完整的信息,存在线程安全的问题

实现代码:

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

3.懒汉式线程安全

加同步关键字,保证线程安全,但是已经实例化的对象也会竞争资源,造成阻塞,性能低

实现代码:

public class Singleton {
    private static Singleton instance=null;
    private Singleton(){}
    public static synchronized Singleton getInstance(){
        //synchronized(Singleton.class){
            if(instance==null){
                instance=new Singleton();
            }
            return instance;
        //}
    }
}

4.双重校验(DCL单例)

可以保证只对需要实例化的代码进行同步,需要加volatile关键字,禁止指令重排序

实现代码:

public class Singleton {
    private static volatile Singleton instance=null;
    private Singleton(){}
    public static Singleton getInstance(){
        if(instance==null){
            synchronized(Singleton.class){
                if(instance==null){               
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
}

5.静态内部类

只有在调用实例化方法时,静态内部类才加载,并且jvm能保证静态内部类只加载一次

实现代码:

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

6.枚举类

可以防止反射攻击

实现代码:

public enum  Singleton {
    INSTANCE;
    public static Singleton getInstance(){
        return INSTANCE;
    }
}

7.测试

测试代码:

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

测试的时候在获取实例方法里加个睡眠操作,更容易看到线程安全问题所带来的破坏

饿汉式测试结果:

在这里插入图片描述

懒汉式测试结果:

在这里插入图片描述

懒汉式线程安全测试结果:

在这里插入图片描述

DCL测试结果:

在这里插入图片描述

静态内部类测试结果:

在这里插入图片描述

枚举类测试结果:

在这里插入图片描述
剑指offer全集入口: 请戳这里

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值