📅  最后修改于: 2023-12-03 14:42:55.353000             🧑  作者: Mango
在Java中,单例模式是一种常用的设计模式,它保证一个类只有一个实例,并且提供了一个全局的访问点。常用的实现方法是使用一个私有的构造函数、一个私有的静态变量以及一个公有的静态方法来实现。
在这种实现方式中,单例类在程序启动时就被创建,所以也叫做“线程安全的单例模式”。
示例代码:
public class Singleton {
private static 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;
}
}
优点:避免了在程序启动时就创建对象,节约了一些资源。
缺点:在多线程环境下,可能会出现多个实例的情况,所以需要加锁来保证线程安全,但是加锁也会影响性能。
在这种实现方式中,单例类的实例是在第一次被访问时才被创建,同时采用双重检查锁的方式来保证线程安全。
示例代码:
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;
}
}
优点:采用了双重检查锁的方式来保证线程安全,同时还避免了每次访问getInstance方法都要加锁的问题,提高了性能。
缺点:由于JVM内存模型的问题,偶尔会出现单例对象还未完全初始化的情况,需要对instance变量加上volatile关键字来避免这种情况。
在这种实现方式中,单例类的实例是在第一次被访问时才被创建,同时使用静态内部类的方式来保证线程安全。
示例代码:
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
优点:采用了静态内部类的方式来保证线程安全,同时还避免了每次访问getInstance方法都要加锁的问题,提高了性能。
缺点:需要了解静态内部类的使用方法,不够直观。