单例模式
单例模式(Singleton Pattern)是一种常用的软件设计模式,它的主要目的是确保一个类仅有一个实例,并提供一个全局访问点来获取这个实例。单例模式在很多场景下都非常有用,比如配置文件读取、数据库连接、线程池等。
使用单例模式改造数据库连接功能
1.加载配置数据
数据库配置信息存储于database.properties配置文件中,具体配置信息如下所示
BaseDao类中的Init()方法负责从database.properties配置文件中加载配置信息
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/store?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username=root
password=123456
2.获取数据库的连接对象
使用Connetion getConnection()方法获取数据连接,返回Connection实例
3.处理查询操作
ResultSet execute(Connection,PreparedStatement,ResultSet,String,Object[])方法:负责根据传入的参数完成数据的查询操作,返回结果集ResultSet
4.处理增、删、改操作
使用 int execute(Connection,PreparedStatement,String,Object[])方法根据传入的参数完成数据的更新(增、删、改)操作,返回影响的行数
5.关闭数据库连接
使用 boolean closeResource(Connection,PreparedStatement,ResultSet)方法,负责根据传入的参数进行相应资源的关闭操作,返回boolean值
实现单例模式的几种方式
1. 懒汉式(线程不安全)
这种方式在类内部声明一个静态对象,在第一次使用时进行实例化。但是,这种实现方式在多线程环境下是不安全的,因为可能同时有多个线程尝试创建实例。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2. 懒汉式(线程安全)
为了解决懒汉式在多线程环境下的安全问题,可以通过在getInstance()
方法上添加synchronized
关键字来实现线程安全,但这样会导致性能下降。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3. 双重检查锁定(Double-Checked Locking)
双重检查锁定模式既实现了延迟加载,又保证了线程安全,同时避免了synchronized
带来的性能问题。
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;
}
}
注意:这里的volatile
关键字非常关键,它确保了在多线程环境下instance
变量的可见性,即一个线程修改了instance
变量的值,其他线程能够立即得知这个修改。
4. 饿汉式
饿汉式在类加载时就完成了初始化,所以它是线程安全的。但是,这种方式无法做到延迟加载。
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
5. 静态内部类
静态内部类方式既实现了延迟加载,又保证了线程安全,同时避免了使用volatile
关键字。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
这种方式利用了classloder
的机制来保证初始化instance
时只有一个线程,因此是线程安全的,同时它避免了在Singleton
类加载时就初始化instance
,达到了延迟加载的效果。