Java - 高并发下单例模式安全性的保证

63 阅读2分钟

在高并发环境下,实现单例模式以确保线程安全,通常需要避免使用懒汉式单例(懒汉式单例在多线程环境下可能会创建多个实例),而采用饿汉式单例或者同步锁来保证实例的唯一性和线程安全。

以下是几种常用的实现方式:

饿汉式单例

饿汉式单例在类加载时就完成了实例的初始化,因此天生就是线程安全的。


public class Singleton {

    private static final Singleton instance = new Singleton();

  


    private Singleton() {

        // 私有构造器

    }

  


    public static Singleton getInstance() {

        return instance;

    }

}

同步锁单例

如果需要懒加载(即在需要时才创建实例),可以使用同步锁来保证线程安全。


public class Singleton {

    private static Singleton instance;

  


    private Singleton() {

        // 私有构造器

    }

  


    public static synchronized Singleton getInstance() {

        if (instance == null) {

            instance = new Singleton();

        }

        return instance;

    }

}

这里使用了 synchronized 关键字来同步 getInstance 方法,但这会带来性能开销,因为每次调用 getInstance 都需要进行同步。

双重检查锁定(Double-Checked Locking)

双重检查锁定是一种在实例未被创建时才同步的方法,它既实现了懒加载,又保证了线程安全。


public class Singleton {

    private static volatile Singleton instance;

  


    private Singleton() {

        // 私有构造器

    }

  


    public static Singleton getInstance() {

        if (instance == null) {

            synchronized (Singleton.class) {

                if (instance == null) {

                    instance = new Singleton();

                }

            }

        }

        return instance;

    }

}

注意,这里使用了 volatile 关键字来确保多个线程都能够正确处理 instance 变量。

使用内部静态类(Bill Pugh Singleton)

这种方式利用了Java类加载机制来保证线程安全,同时实现了懒加载。


public class Singleton {

    private Singleton() {

        // 私有构造器

    }

  


    private static class Holder {

        private static final Singleton INSTANCE = new Singleton();

    }

  


    public static Singleton getInstance() {

        return Holder.INSTANCE;

    }

}

以上就是在高并发环境下保证单例模式线程安全的一些常用方法。选择哪种方式取决于具体的需求和场景。