首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 設計模式精講:Singleton 單例模式兩大經典實作與資料庫連線池實戰應用

     編輯:Java 相關知識

模式意圖

確保執行期應用程式中,某個類別**僅被實例化一次**,提供全域唯一存取點。Web 應用的核心分發 Servlet 即典型應用場景。

實作形式一:餓漢式(類載入即建立實例)

public class Singleton {
    private Singleton() {} // 私有建構子
    private static final Singleton instance = new Singleton(); // 靜態常量持有實例
    public static Singleton getInstance() {
        return instance; // 直接返回
    }
}

優點:簡單、線程安全(類載入機制保證)、無同步開銷。
缺點:類載入即佔用記憶體,若未使用造成浪費。

實作形式二:懶漢式(雙重檢查鎖定 / 同步方法)

public class Singleton {
    private static volatile Singleton instance = null;
    public static Singleton getInstance() {
        if (instance == null) { // 第一次檢查
            synchronized (Singleton.class) {
                if (instance == null) { // 第二次檢查
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

優點:首次使用才建立,節省記憶體。
關鍵:volatile 禁止指令重排序,雙重檢查避免多執行緒重複建立。

實戰案例:資料庫連線管理器 (DBManager)

public class DBManager {
    private static final Logger logger = Logger.getLogger(DBManager.class);
    private static DataSource dataSource;
    // 餓漢式單例
    private static final DBManager dbConManager = new DBManager();
    private DBManager() {}
    public void setDataSource(DataSource ds) {
        if (dataSource == null) dataSource = ds;
    }
    public static DBManager getInstance() {
        logger.info("獲取資料庫連線管理器實例");
        return dbConManager;
    }
    public Connection getConnection() throws SQLException {
        Connection conn = null;
        try {
            logger.info("從連線池獲取閒置連線");
            conn = dataSource.getConnection();
            return conn;
        } catch (SQLException ex) {
            logger.error("獲取連線失敗: " + ex.getMessage());
            throw ex;
        }
    }
    public void closeAll(Connection conn, Statement st, PreparedStatement pst,
                         CallableStatement cst, ResultSet rs) throws DBManagerException {
        try {
            if (rs != null) rs.close();
            if (st != null) st.close();
            if (pst != null) pst.close();
            if (cst != null) cst.close();
            if (conn != null) conn.close();
        } catch (SQLException e) {
            throw new DBManagerException("資料庫物件關閉出錯: " + e.getMessage(), e);
        }
    }
}

設計亮點:
✅ 單例封裝連線池存取邏輯
✅ 統一異常處理與日誌記錄
✅ closeAll 簡化資源釋放,避免重複樣板碼
✅ Struts 啟動時注入 DataSource,解耦框架依賴

選型建議

  • 一般情況:餓漢式更安全、簡單、效能足夠。
  • 實例建立極其耗時/佔用巨大資源且使用率低:考慮懶漢式(需正確處理 volatile 與雙重檢查)。
  • 嚴禁反射/序列化破壞單例:可在建構子中檢查 instance != null 拋異常,實作 readResolve() 返回現有實例。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved