知识问答

Java设计模式系列之深入浅出单例模式

下面我来为你详细讲解“Java设计模式系列之深入浅出单例模式”的完整攻略。

标题

什么是单例模式

单例模式是一种常用的设计模式之一,用于保证在整个应用程序中,某个类只有一个实例存在,并且提供一个全局访问点。

实现单例模式

实现单例模式可以采用以下方式:

饿汉式

饿汉式是在类被加载时就将实例化对象的过程完成。比较简单,但是在可能没有使用到该实例时也会被实例化,浪费了内存资源。

示例代码:

public class Singleton {    private static Singleton instance = new Singleton();    private Singleton() {}    public static Singleton getInstance() {        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 volatile static Singleton instance;    private Singleton() {}    public static Singleton getInstance() {        if(instance == null) {            synchronized(Singleton.class) {                if(instance == null) {                    instance = new Singleton();                }            }        }        return instance;    }}

静态内部类式

静态内部类式是在第一次使用该实例的时候才会进行实例化,并且使用了Java虚拟机对静态内部类的特殊处理,保证线程安全和高效性。

示例代码:

public class Singleton {    private Singleton() {}    private static class SingletonHolder {        private static final Singleton INSTANCE = new Singleton();    }    public static Singleton getInstance() {        return SingletonHolder.INSTANCE;    }}

单例模式的应用场景

单例模式适用于以下场景:

  1. 系统只需要一个实例对象,如Windows操作系统中的任务管理器。
  2. 对象需要被共享的场合,如线程池、数据库连接池等。
  3. 频繁创建和销毁对象会造成系统性能问题的场合,如IO操作、数据库操作等。

总结

单例模式是一种常用的设计模式,它保证在整个应用程序中某个类只有一个实例,并提供了一个全局访问点。单例模式的实现有多种方式,常用的包括饿汉式、懒汉式、双重校验锁式和静态内部类式。在应用中需要考虑线程安全、性能和内存等因素,选择合适的实现方式。

  1. 示例一:使用单例模式实现读取配置文件的工具类。
public class ConfigUtil {    private static final String CONFIG_FILE_PATH = "config.properties";    private Properties properties;    private ConfigUtil() {        // 加载配置文件        try {            properties = new Properties();            InputStream inStream = getClass().getClassLoader().getResourceAsStream(CONFIG_FILE_PATH);            properties.load(inStream);        } catch (IOException e) {            e.printStackTrace();        }    }    private static class SingletonHolder {        private static final ConfigUtil INSTANCE = new ConfigUtil();    }    public static ConfigUtil getInstance() {        return SingletonHolder.INSTANCE;    }    public String getProperty(String key, String defaultValue) {        return properties.getProperty(key, defaultValue);    }}
  1. 示例二:使用单例模式实现计数器。
public class Counter {    private int count;    private Counter() {        count = 0;    }    private static class SingletonHolder {        private static final Counter INSTANCE = new Counter();    }    public static Counter getInstance() {        return SingletonHolder.INSTANCE;    }    public synchronized void add() {        count++;    }    public synchronized int getCount() {        return count;    }}