单例模式是一种对象创建模式,用于产生一个对象的具体实例,并确保系统中这个类只产生一个实例。
使用单例模式的好处:
(1)对于频繁使用的对象,像数据库操作使用JDBC连接,可以省略创建对象所花费的时间,减少系统开销。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public final class JdbcUtil {
private final String url = "jdbc:mysql://localhost:3306/jdbc";
private final String user = "root";
private final String password = "";
private static JdbcUtil jdbcInstance = null;
private JdbcUtil(){}
public static JdbcUtil getJdbcInstance(){
if(jdbcInstance == null){
synchronized (JdbcUtil.class) {
if(jdbcInstance == null)
jdbcInstance = new JdbcUtil();
}
}
return jdbcInstance;
}
static{
try{
Class.forName("com.mysql.jdbc.Driver");
}catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}
public Connection getConn(){
try {
return DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public void releaseConn(ResultSet rs,Statement st,Connection conn){
try {
if(rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
if(st!=null)
st.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(conn!=null)
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
【注】平常写代码,尽量少用try/catch,影响运行效率。
(2)降低内存使用频率,减轻GC压力,缩短GC停顿时间。
角色:
单例类:提供单利的工厂,返回单例。
调用者:获取并使用单例。
1、一个简单实现(无延迟加载)
public class Singleton{
private Singleton(){
System.out.println("singleton is created");
}
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
2、延迟加载
public class LazySingleton {
private LazySingleton() {
}
private static LazySingleton instance = null;
public static synchronized LazySingleton getInstance() {
if (instance == null)
instance = new LazySingleton();
return instance;
}
}
虽然实现了延迟加载,但是基于线程安全的考虑,加入了同步关键字,导致效率大大降低。
3、使用内部类
public class StaticSingleton {
private StaticSingleton() {
}
private static class SingletonHolder {
private final static StaticSingleton instance = new StaticSingleton();
}
public static StaticSingleton getInstance() {
return SingletonHolder.instance;
}
}
使用内部类,由于实例的建立是在类加载时完成的,故对多线程友好。同时,实现了延迟加载。