Java单例模式实现与线程安全性解析

需积分: 0 0 下载量 190 浏览量 更新于2024-08-05 收藏 8KB MD 举报
"这篇文章主要探讨了6种不同的单例模式实现方法,并关注它们是否线程安全。内容包括:饿汉式、懒汉式、双重检查锁定(DCL)、静态内部类、枚举以及同步方法。" 在软件设计模式中,单例模式是一种限制类实例化次数,确保一个类只有一个实例并提供全局访问点的设计模式。以下是6种单例模式的实现方式及其线程安全性: 1. 饿汉式: 这种实现方式在类加载时就创建了单例对象,因此是线程安全的。示例代码中,`uniqueInstance`在静态初始化阶段被创建,确保多线程环境下的唯一性。 ```java public class Singleton { private static Singleton uniqueInstance = new Singleton(); private Singleton() {} public static Singleton getUniqueInstance() { return uniqueInstance; } } ``` 2. 懒汉式: 懒汉式在第一次调用`getUniqueInstance()`时才创建单例对象。原始的懒汉式实现非线程安全,因为多个线程可能同时进入`if(uniqueInstance == null)`判断,导致创建多个实例。 ```java public class Singleton { private static Singleton uniqueInstance; private Singleton() {} public static Singleton getUniqueInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } } ``` 3. 双重检查锁定(DCL): DCL解决了懒汉式的线程安全问题。在创建实例前添加了额外的同步检查,确保多线程环境下只有一个实例被创建。 ```java public class Singleton { private static volatile Singleton uniqueInstance; private Singleton() {} public static Singleton getUinqueInstance() { if (uniqueInstance == null) { synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } } ``` 4. 静态内部类: 静态内部类保证了线程安全,因为类加载时只会初始化一次。这种方式既延迟了初始化,又避免了同步开销。 ```java public class Singleton { private static class SingletonHolder { private static final Singleton uniqueInstance = new Singleton(); } private Singleton() {} public static Singleton getUniqueInstance() { return SingletonHolder.uniqueInstance; } } ``` 5. 枚举: 使用枚举实现单例模式是最简洁且线程安全的方式,Java枚举的初始化是线程安全的。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { } } ``` 6. 同步方法: 将获取单例的方法设置为`synchronized`,这样每次只有一个线程能执行`getUniqueInstance()`,确保线程安全,但会降低性能。 ```java public class Singleton { private static Singleton uniqueInstance; private Singleton() {} public static synchronized Singleton getUinqueInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } } ``` 选择哪种实现方式取决于性能、线程安全和代码简洁性的需求。通常,静态内部类和枚举是推荐的选择,因为它们既简单又线程安全。