Java单例设计模式
定义
单例设计模式是一种常用的软件设计模式,它确保一个类只有一个实例,并且自行实例化并向整个系统提供这个实例。这种模式的目的是限制类的实例化次数,并提供一个全局访问点来访问该实例。单例模式通常用于管理共享资源,例如数据库连接或线程池。它可以减少内存开销,避免对资源的多重占用,并且可以在整个应用程序中共享数据。
优缺点
优点
- 节省内存和计算,实例只创建一次,不必重复创建。
- 保证结果正确,比如单例计数器,用作多线程的数据统计。
- 方便管理,例如日期工具类,字符串工具类,不需要创建那么多的实例。
缺点
- 当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new,可能会给其他开发人员造成困扰,特别是看不到源码的时候。
应用场景
- 无状态的工具类:比如日志工具类,不管是在哪里使用,我们需要的只是它帮我们记录日志信息,除此之外,并不需要在它的实例对象上存储任何状态,这时候我们就只需要一个实例对象即可。
- 全局信息类:比如我们在一个类上记录网站的访问次数,我们不希望有的访问被记录在对象A上,有的却记录在对象B上,这时候我们就让这个类成为单例。
实例
以下列出八种单例设计模式实例:
饿汉式——静态常量(可用)
public class Singleton1 {
private final static Singleton1 INSTANCE = new Singleton1();
private Singleton1() {}
public static Singleton1 getInstance() {
return INSTANCE;
}
}
饿汉式——静态代码块(可用)
public class Singleton2 {
private final static Singleton2 INSTANCE;
static {
INSTANCE = new Singleton2();
}
private Singleton2() {}
public static Singleton2 getInstance() {
return INSTANCE;
}
}
懒汉式——线程不安全(不可用)
public class Singleton3 {
private static Singleton3 instance;
private Singleton3() {}
public static Singleton3 getInstance() {
if (instance == null) {
instance = new Singleton3();
}
return instance;
}
}
懒汉式——线程安全,同步方法(不推荐用)
public class Singleton4 {
private static Singleton4 instance;
private Singleton4() {}
public synchronized static Singleton4 getInstance() {
if (instance == null) {
instance = new Singleton4();
}
return instance;
}
}
懒汉式——线程不安全,同步代码块(不推荐)
public class Singleton5 {
private static Singleton5 instance;
private Singleton5() {}
public static Singleton5 getInstance() {
if (instance == null) {
synchronized (Singleton5.class) {
instance = new Singleton5();
}
}
return instance;
}
}
双重检查(推荐面试用)
public class Singleton6 {
private volatile static Singleton6 instance;
private Singleton6() {}
public static Singleton6 getInstance() {
if (instance == null) {
synchronized (Singleton6.class) {
if (instance == null) {
instance = new Singleton6();
}
}
}
return instance;
}
}
静态内部类(可用)
public class Singleton7 {
private Singleton7() {}
private static class SingletonInstance {
private static final Singleton7 INSTANCE = new Singleton7();
}
public static Singleton7 getInstance() {
return SingletonInstance.INSTANCE;
}
}
枚举(推荐用)
public enum Singleton8 {
INSTANCE;
public void getInstance() {}
}