Java单例模式的6种实现方式详解
前言
单例模式是一种常见的设计模式,它可以保证一个类只有一个实例,并为外界提供唯一的访问入口。在实际开发中,单例模式经常被用于创建一些共享资源的场景,如数据库连接池、线程池等。本文将详细介绍Java中单例模式的六种实现方式。
1. 饿汉式(静态常量)
饿汉式单例模式的实现方式非常简单,就是在类加载的时候立即创建单例对象,因此也被称为静态常量方式。
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
使用场景:适用于单例对象较小,没有过多的资源占用的情况下。
示例:
public class Main {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // 输出 true
}
}
2. 饿汉式(静态代码块)
饿汉式单例模式的一种变种是静态代码块方式,它与静态常量方式的区别在于在静态代码块中可以进行一些初始化操作。
public class Singleton {
private static final Singleton INSTANCE;
static {
INSTANCE = new Singleton();
// 在这里进行初始化操作
}
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
使用场景:适用于单例对象需要进行一些初始化操作的情况下。
示例:
public class Main {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // 输出 true
}
}
3. 懒汉式(线程不安全)
懒汉式单例模式的实现方式是在第一次调用getInstance()方法时创建单例对象,如果同时有多个线程并发调用该方法,可能会创建多个实例,因此这种实现方式是线程不安全的。
public class Singleton {
private static Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
使用场景:适用于单例对象较大,多线程情况比较少的情况下。
示例:
public class Main {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // 输出 true
}
}
4. 懒汉式(线程安全,同步方法)
为了解决线程安全问题,可以在getInstance()方法上添加synchronized关键字,保证多个线程调用该方法时只会创建一个单例对象,但是这种方式会降低并发性能。
public class Singleton {
private static Singleton INSTANCE;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
使用场景:适用于单例对象较大,多线程情况比较多的情况下。
示例:
public class Main {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // 输出 true
}
}
5. 懒汉式(线程安全,双重校验锁)
双重校验锁是目前线程安全的懒汉式单例模式实现方式,它采用了同步代码块和synchronized关键字的结合使用,解决了线程安全和并发性能问题。
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;
}
}
使用场景:适用于单例对象较大,多线程情况比较多的情况下。
示例:
public class Main {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // 输出 true
}
}
6. 枚举
枚举方式是目前最简单、最安全、最优雅的单例模式实现方式,它能够解决所有单例模式的问题,而且代码非常简洁明了。
public enum Singleton {
INSTANCE;
// 枚举类中的其他成员变量和成员方法
}
使用场景:适用于最简单、最安全、最优雅的单例模式实现方式。
示例:
public class Main {
public static void main(String[] args) {
Singleton instance1 = Singleton.INSTANCE;
Singleton instance2 = Singleton.INSTANCE;
System.out.println(instance1 == instance2); // 输出 true
}
}
结语
以上就是Java中单例模式的六种实现方式,各有优缺点,需要根据具体情况选择。如果不要求延迟加载,可以选择饿汉式,否则应该选择懒汉式;如果需要保证线程安全,可以选择双重校验锁或枚举方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java单例模式的6种实现方式详解 - Python技术站