单例模式总结(Java)

单例模式总结(Java)

单例模式是一个特别常用的设计模式,面试中手撕单例模式也是非常常见的,所以我在这里对单例模式的写法
进行了总结。
一、饿汉式(静态变量直接实例化、静态代码块处实例化)
二、懒汉式(非线程安全、线程安全、双重检查DCL)
三、静态内部类
四、枚举
public class Singleton {
    public static void main(String[] args){
        //主方法创建单例对象
        SingletonTest1 singletonTest1 = SingletonTest1.getInstance();
        SingletonTest2 singletonTest2 = SingletonTest2.getInstance();
        SingletonTest3 singletonTest3 = SingletonTest3.getInstance();
        SingletonTest7 singletonTest7 = SingletonTest7.getInstance();
        SingletonTest4 singletonTest4 = SingletonTest4.getInstance();
        SingletonTest5 singletonTest5 = SingletonTest5.getInstance();
        SingletonTest6 singletonTest6 = SingletonTest6.INSTANCE;
    }
}
/*
饿汉式在类加载的时候会进行实例化操作
会造成一定的内存浪费,因为不管你是否使用该实例,只要类加载,就会实例化
下面两种方式本质上是一样的
*/
//饿汉式(静态变量,线程安全,推荐)
class SingletonTest1{
    private final static SingletonTest1 INSTANCE = new SingletonTest1();
    private SingletonTest1(){

    }
    public static SingletonTest1 getInstance(){
        return INSTANCE;
    }
}

//饿汉式(静态代码块,线程安全)
class SingletonTest2{
    private static SingletonTest2 instance;
    static{
        instance = new SingletonTest2();
    }
    private SingletonTest2(){

    }
    public static SingletonTest2 getInstance(){
        return instance;
    }
}
/*
懒汉式解决了饿汉式内存浪费的问题
只有在调用getInstance方法的时候才会经行实例化
但是需要考虑线程安全问题
*/
//懒汉式(多线程不安全)
class SingletonTest3{
    private static SingletonTest3 instance;
    private SingletonTest3(){}
    public static SingletonTest3 getInstance(){
        if (instance == null){
            instance = new SingletonTest3();
        }
        return instance;
    }
}
//懒汉式(线程安全,加锁)
class SingletonTest7{
    private static SingletonTest7 instance;
    private SingletonTest7(){}
    public synchronized static SingletonTest7 getInstance(){
        if(instance == null){
            instance = new SingletonTest7();
        }
        return instance;
    }
}
/*
懒汉式(DCL双重检查单例模式,线程安全,推荐)
DCL是一个包含特别多知识点的实现方式
为什么双重检验?
volatile关键字的作用,是否可以省略?
synchronized等
*/
class SingletonTest4{
    private static volatile SingletonTest4 instance;
    private SingletonTest4(){}
    public static SingletonTest4 getInstance(){
        if (instance == null){
            synchronized(SingletonTest4.class){
                if(instance == null){
                    instance = new SingletonTest4();
                }
            }
        }
        return instance;
    }
}
/*
静态内部类方式(线程安全,推荐)
解决了内存浪费问题:
在外部类进行类加载的时候不会对它的内部类经行加载
当调用getInstance方法时,会对静态内部类Inner进行加载,并对外部类经行实例化
无需考虑线程安全问题:
因为JVM层面保证了类加载的安全性,所以该方式和饿汉式一样都是线程安全的
*/
class SingletonTest5{
    private SingletonTest5(){}
    private static class Inner{
        private final static SingletonTest5 INSTANCE = new SingletonTest5();
    }
    public static SingletonTest5 getInstance(){
        return Inner.INSTANCE;
    }
}
//枚举(线程安全,可以防止反序列换创建新的对象,推荐)
enum SingletonTest6{
    INSTANCE;
}
大概就这么多了,下一篇文章我可能会针对上面的DCL双重检查模式中涉及到的一些问题给大家做一下分享
这是我的第一篇文章,希望大家多多支持呀!

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值