好程式設計師Java學習路線分享MyBatis之執行緒最佳化

好程式設計師IT發表於2019-09-19

  好程式設計師Java 學習路線分享 MyBatis 之執行緒最佳化,我們的專案存在大量使用者同時訪問的情況,那麼就會出現大量執行緒併發訪問資料庫,這樣會帶來執行緒同步問題,本章我們將討論 MyBatis 的執行緒同步問題和最佳化方法。

 

MyBatis 的執行緒同步問題

MyBatis 需要透過 SqlSession 實現資料庫操作,而 SQLSession 內部的實現需要使用 JDBC Connection 連線物件,而 Connection 物件是非執行緒安全的,當多個執行緒同時

訪問時,就可能出現執行緒同步的問題。

執行緒同步的解決方法

我們前面學習過解決執行緒同步的方法是:鎖機制

我們可以給所有資料庫相關方法或程式碼新增synchronized 關鍵字,本質上是讓所有執行緒排隊執行這些操作。


這樣解決了執行緒同步問題,但是會帶來執行效率的降低,如果大量的使用者訪問時會導致長時間的等待,所以今天我們將學習另一種解決方法。

ThreadLocal 解決執行緒同步

ThreadLocal (執行緒區域性變數),可以為每個執行緒建立物件的副本,這樣就不存在多執行緒訪問一個物件的情況,以空間換時間,效率高,速度快,但是記憶體空間消耗更大。


ThreadLocal 的用法

建立方法:

ThreadLocal< 資料的型別 > threadLocal = new ThreadLocal< 資料型別 >();

資料的型別是每個執行緒中需要儲存資料的型別

資料存取:

void set(Object  資料 將資料和當前執行緒繫結起來

Object get()  從當前執行緒中獲得繫結的資料

 

Session 執行緒安全的最佳化方法

1 )建立 ThreadLocal 來儲存 SqlSession

2 )編寫獲得 SqlSession 的方法

1 )呼叫 ThreadLocal get 方法來獲得 SqlSession

2 )如果 SqlSession 物件為 null ,呼叫工廠來建立 SqlSession ,使用 ThreadLocal set 方法儲存到執行緒中,返回 SqlSession 物件

3 )如果 SqlSession 物件不為 null ,就直接返回

示例程式碼:

/**

 * MyBatis 工具類

 *  用於獲得當前執行緒中的 SqlSession

 *  使用 ThreadLocal 解決執行緒安全問題

 */

public class MyBatisUtils {

 

    public static final String CONFIG_FILENAME = "mybatis-config.xml";

    // 使用 ThreadLocal 儲存 SQLSession 物件

    private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();

    //SqlSession 的工廠,單例

    private static SqlSessionFactory factory = null;

    /**

     *  建立工廠

     */

    public static void buildFactory(){

        try {

            factory = new SqlSessionFactoryBuilder().build(

                    Resources.getResourceAsStream(CONFIG_FILENAME));

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    // 在靜態程式碼塊中執行,保證工廠的建立只執行一次

    static{

        buildFactory();

    }

    /**

     *  從當前執行緒中獲得 Session

     * @return

     */

    public static SqlSession getSession(){

        // ThreadLocal 獲得執行緒中的 SqlSession

        SqlSession sqlSession = threadLocal.get();

        if(sqlSession == null){

            // 如果 SqlSession 為空,建立 SqlSession

            if(factory == null){

                buildFactory();

            }

            sqlSession = factory.openSession();

            // 把新建立的 SqlSession ,存入到 ThreadLocal, 繫結到執行緒中

            threadLocal.set(sqlSession);

        }

        return sqlSession;

    }

    /**

     *  關閉 Session

     */

    public static void closeSession(){

        // ThreadLocal 獲得執行緒中的 SqlSession

        SqlSession sqlSession = threadLocal.get();

        if(sqlSession != null){

            // 關閉會話

            sqlSession.close();

            // 設定為 null gc 會盡快回收

            sqlSession = null;

            // 刪除掉 ThreadLocal 中的 SqlSession

            threadLocal.set(null);

        }

    }

}

 

總結

執行緒同步是進行JavaEE 開發需要重點考慮的問題, MyBatis SQLSession 有執行緒同步問題,使用 ThreadLocal 為每個執行緒繫結自己的 SQLSession 副本,可以解決執行緒同步問題,同時不會降低程式執行效率。

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2657526/,如需轉載,請註明出處,否則將追究法律責任。

相關文章