Java单例模式源码剖析及使用场景

一、 饿汉式

这种方式在类加载时就完成了实例的创建,是线程安全的。

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 Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

三、懒汉式(线程安全,同步方法)

为了解决上述线程不安全问题,可以将getInstance()方法加同步锁。但是会造成不必要的同步开销。

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

四、懒汉式(线程安全,同步代码块)

这种方式相比于同步方法,可以减少不必要的同步开销。

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

五、双重检查锁定

这种方式是单例模式的经典实现方式,兼顾了线程安全性和性能。

public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {}

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

六、静态内部类

这种方式利用了类加载机制来保证线程安全,也是一种比较好的实现方式。

public class Singleton {
    private Singleton() {}

    private static class SingletonHolder {
        private static final Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

七、枚举单例

这种方式是最简单的单例模式实现,由JVM从根本上确保了线程安全和单例。

public enum Singleton {
    INSTANCE;

    public void doSomething() {
        // ...
    }
}

每种实现方式各有优缺点:

  • 饿汉式简单,但可能造成内存浪费。
  • 懒汉式节省资源,但需要处理线程安全问题。
  • 双重检查锁定是较优的一种实现。
  • 静态内部类利用了类加载机制,是一种比较好的实现方式。
  • 枚举单例最简单,由JVM保证线程安全和单例。

在实际开发中,可根据应用场景选择合适的单例实现方式。如果对单例对象的使用率较高,可以选择饿汉式或静态内部类的实现方式;如果对单例对象的使用率不太高,可以选择懒汉式或双重检查锁定的实现方式;如果项目中习惯使用枚举类,也可以采用枚举单例的实现方式。

八、 通俗理解

单例模式的核心思想是控制实例的创建,确保单例类只有一个实例对象。我们可以把它比作一个公司只有一个老板,不管从哪个门进去,看到的都是同一个老板。这样的好处是可以节省资源,避免对象的重复创建和销毁。

九、项目案例

在项目开发中,单例模式被广泛应用。例如,我们常常需要维护一个配置文件对象,用于存储系统的配置信息。由于配置数据对于整个系统来说是相同的,因此我们只需要创建一个实例即可。

public class ConfigManager {
    private static ConfigManager instance;
    private Map<String, String> configs;

    private ConfigManager() {
        configs = loadConfigsFromFile();
    }

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

    public String getConfig(String key) {
        return configs.get(key);
    }

    private Map<String, String> loadConfigsFromFile() {
        // 从文件加载配置信息
    }
}

在上面的例子中,ConfigManager类通过私有构造函数和静态的getInstance()方法实现了单例模式。我们可以在任何需要访问配置信息的地方使用ConfigManager.getInstance()获取单例对象。

十、Java源码案例

在java.lang标准库中,也存在一些单例模式的实现。比如,Runtime类就是一个典型的单例类,用于获取与当前Java应用程序相关的运行时对象。

public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    private Runtime() {}
    // 其他方法...
}

在Runtime类的实现中,通过一个私有静态变量currentRuntime持有单例实例,getRuntime()方法返回这个实例。私有构造函数确保了外部无法直接创建Runtime对象。

总的来说,单例模式可以通过私有化构造函数、提供静态方法获取实例等方式实现。它确保了应用程序中一个类只有一个实例,从而节省资源,并提供了一个全局访问点。

  • 28
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java语录精选

你的鼓励是我坚持下去的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值