您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關Hibernate中怎么利用ThreadLocal模式管理Session,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
一、ThreadLocal模式 (線程局部變量模式) 管理Session的理解
(1)在利用Hibernate開發的時候如何合理的管理Session,避免Session的頻繁創建和銷毀,對于提高系統的性能來說是非常重要的!
(2)我們知道Session是由SessionFactory負責創建的,而SessionFactory的實現是線程安全的,多個并發的線程可以同時訪問一個SessionFactory并從中獲取Session實例,但是遺憾的是Session不是線程安全的。
(3)Session中包含了數據庫操作相關的狀態信息,那么說如果多個線程同時使用一個Session實例進行CRUD(數據庫的增刪改查),就很有可能導致數據存取的混亂,我們根本無法想像那些你根本不能預測執行順序的線程對你的一條記錄進行操作的情形!
(4)在Session的眾多管理方案中,在今天的學習中知道ThreadLocal模式是一種很不錯的解決方案,特分享給大家!
(5)我們首先要明白的是ThreadLocal并非是一個線程的本地實現版本,它并不是一個Thread,而是thread local variable(線程局部變量)。(也許把它命名為ThreadLocalVar更加合適)。線程局部變量(ThreadLocal)其實的功用非常簡單,就是為每一個使用某變量的線程都提供一個該變量值的副本,是每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本沖突。從線程的角度看,就好像每一個線程都完全擁有一個該變量。
(6)更具體的來說就是:ThreadLocal并非等同于線程成員變量,ThreadLocal該類提供了線程局部變量。這個局部變量與一般的成員變量不一樣,ThreadLocal的變量在被多個線程使用時候,每個線程只能拿到該變量的一個副本,這是Java API中的描述,但更準確的說,應該是ThreadLocal類型的變量內部的注冊表(Map<Thread,T>)發生了變化,但ThreadLocal類型的變量本身的確是一個,這才是本質!
(7)ThreadLocal的原理:在ThreadLocal類中有一個Map,用于存儲每一個線程的變量的副本。比如下面的示例實現:
public class ThreadLocal { <span > </span>private Map values = Collections.synchronizedMap(new HashMap()); <span > </span>public Object get() { <span > </span>Thread curThread = Thread.currentThread(); <span > </span>Object o = values.get(curThread); <span > </span>if (o == null && !values.containsKey(curThread)) { <span > </span>o = initialValue(); <span > </span>values.put(curThread, o); <span > </span>} <span > </span>values.put(Thread.currentThread(), newValue); <span > </span>return o; <span > </span>} <span > </span>public Object initialValue() { <span > </span>return null; <span > </span>} }
二、代碼的展示
(1)使用ThreadLocal模式 (線程局部變量模式) 管理Session的代碼如下:
<span >package com.lc.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * 升級的MySessionFactory 線程局部模式 * @author xuliugen */ public class HibernateUtil { private static SessionFactory sessionFactory = null; // 使用線程局部模式 private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); /* * 默認的構造函數 */ private HibernateUtil() { } /* * 靜態的代碼塊 */ static { sessionFactory = new Configuration().configure().buildSessionFactory(); } /* * 獲取全新的的session */ public static Session openSession() { return sessionFactory.openSession(); } /* * 獲取和線程關聯的session */ public static Session getCurrentSession() { Session session = threadLocal.get(); // 判斷是是是否得到 if (session == null) { session = sessionFactory.openSession(); // 把session放到 threadLocal,相當于該session已經于線程綁定 threadLocal.set(session); } return session; } }</span>
(2)測試代碼如下:
<span >package com.lc.view; import org.hibernate.Session; import com.lc.util.HibernateUtil; public class TestHibernateUtil { public static void main(String[] args) { Session s1 = HibernateUtil.getCurrentSession(); Session s2 = HibernateUtil.getCurrentSession(); System.out.println(s1.hashCode()+" "+s2.hashCode()); /* * 1432950766 1432950766 * 結果是兩個hashCode是一樣的,證明是線程相關的 */ } }</span><span > </span>
看完上述內容,你們對Hibernate中怎么利用ThreadLocal模式管理Session有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。