0
点赞
收藏
分享

微信扫一扫

java实现单例的5种方法,快收藏

看山远兮 2022-03-16 阅读 25

1、饿汉式
饿汉式就是类加载后就创建好了单例,直接拿就行,但该方法容易产生垃圾

public class Singleton1 {
    //构造器私有化 防止外部实例
    private Singleton1() {
    }

    private static final Singleton1 SINGLETON_1 = new Singleton1();

    public static Singleton1 getInstance(){
        return SINGLETON_1;
    }
}

2、懒汉式,线程不安全
懒汉式就是,只有我使用的时候才去创建对象,但多线程条件下可能会破坏单例

public class Singleton2 {
	//构造器私有化 防止外部实例
    private Singleton2(){
    }

    private static  Singleton2 SINGLETON_2;

    public static  Singleton2 getInstance(){
        if (SINGLETON_2 == null){
            SINGLETON_2 = new Singleton2();
        }
        return SINGLETON_2;
    }
}

3、线程安全的懒汉式

使用volatile防止了指令重排,不加可能会产生半初始化对象(加载了但没有执行构造函数)
使用synchronized时对象为null时使线程同步防止创建多个对象

public class Singleton3 {

    private Singleton3(){
    }

    private static volatile Singleton3 SINGLETON_3;

    public static Singleton3 getInstance(){
        if (SINGLETON_3 == null){
            synchronized(Singleton3.class){
                SINGLETON_3 = new Singleton3();
            }
        }
        return SINGLETON_3;
    }
}

4、使用静态内部类实现懒汉式单例
使用静态内部类去创建单例,因为静态内部类只会实例化一次,所以第一次实例化以后,每次拿到的都是同一个对象,都是那个静态常量

public class Singleton5 {

    private Singleton5(){
    }

    private static Singleton5 singleton5;

    public static Singleton5 getInstance(){
        return SingletonHander.singleton;
    }

    private static class SingletonHander{
        private static final Singleton5 singleton = new Singleton5();
    }
}

使用枚举实现懒汉式单例

《Effective Java》

这种方法在功能上与公有域方法相近,但是它更加简洁,无偿提供了序列化机制,绝对防止多次实例化,即使是在面对复杂序列化或者反射攻击的时候。虽然这种方法还没有广泛采用,但是单元素的枚举类型已经成为实现 Singleton的最佳方法。—-《Effective Java 中文版 第二版》

public class Singleton4 implements Serializable {

    @Serial
    private static final long serialVersionUID = -2675976638179016828L;
    //构造器私有化
    private Singleton4(){
    }

    private static  Singleton4 SINGLETON4;

    //调用该方法就会执行SingletonHander.instance.singleton4;执行这个方法就会
    //加载内部枚举,加载内部枚举类然后会创建一个枚举项,一个枚举项就是一个枚举的实例
    //所以在创建一个枚举项时会调用内部枚举的构造方法,从而创建一个单例
    public static Singleton4 getInstance(){
        return SingletonHander.instance.singleton4;
    }

    private enum SingletonHander{
        instance;//枚举项,每个枚举项只会创建一个
        private final Singleton4 singleton4;

        SingletonHander() {
            singleton4 = new Singleton4();
        }
    }
}
举报

相关推荐

0 条评论