Hibernate manages Session with ThreadLocal mode of thread local variable mode

  • 2021-07-10 19:47:29
  • OfStack

Hibernate ThreadLocal

It maintains 1 private variable space for each thread. In fact, its implementation principle is to maintain an Map in JVM, and key of this Map is the current thread object, while value is the object instance saved by the thread through Hibernate ThreadLocal. set method. When a thread calls the Hibernate ThreadLocal. get method, Hibernate ThreadLocal will take out the corresponding object in Map and return it according to the reference of the current thread object.

In this way, Hibernate ThreadLocal isolates variables from different threads by distinguishing them by references to individual thread objects.

1. ThreadLocal Mode (Thread Local Variable Mode) Managing Session Understanding

(1) How to manage Session reasonably and avoid frequent creation and destruction of Session when developing with Hibernate is very important for improving the performance of the system!

(2) We know that Session is created by SessionFactory, and the implementation of SessionFactory is thread-safe. Multiple concurrent threads can access one SessionFactory at the same time and get Session instance from it, but unfortunately Session is not thread-safe.

(3) Session contains the state information related to database operation, so if multiple threads use one Session instance for CRUD (database addition, deletion and modification) at the same time, it is very likely to lead to confusion of data access, and we can't imagine those threads that you can't predict the execution order at all to operate on your record!

(4) Among the many management schemes of Session, I know that ThreadLocal mode is a very good solution in today's study, and I would like to share it with you!

(5) The first thing to understand is that ThreadLocal is not a native implementation version of one thread, it is not an Thread, but an thread local variable (thread local variable). (Perhaps it would be more appropriate to name it ThreadLocalVar). Thread local variable (ThreadLocal) actually has a very simple function, that is, it provides a copy of the value of a variable for every thread that uses it, but every thread can change its own copy independently without conflicting with the copies of other threads. From the thread point of view, it is as if every thread has one of the variables completely.

(6) More specifically, ThreadLocal is not equivalent to thread member variables, but ThreadLocal provides thread local variables. This local variable is different from a member variable like 1. When the variable of ThreadLocal is used by multiple threads, each thread can only get one copy of the variable, which is described in Java API, but more accurately, it should be the registry inside the variable of ThreadLocal type (Map) < Thread,T > ), but the ThreadLocal type variable itself is one, that's the essence!

(7) How ThreadLocal works: There is one Map in the ThreadLocal class that stores copies of variables for each thread. For example, the following example implementation:


public class ThreadLocal {
<span style="white-space:pre"> </span>private Map values = Collections.synchronizedMap(new HashMap());
<span style="white-space:pre"> </span>public Object get() {
<span style="white-space:pre"> </span>Thread curThread = Thread.currentThread();
<span style="white-space:pre"> </span>Object o = values.get(curThread);
<span style="white-space:pre"> </span>if (o == null && !values.containsKey(curThread)) {
<span style="white-space:pre">  </span>o = initialValue();
<span style="white-space:pre">  </span>values.put(curThread, o);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>values.put(Thread.currentThread(), newValue);
<span style="white-space:pre"> </span>return o;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public Object initialValue() {
<span style="white-space:pre"> </span>return null;
<span style="white-space:pre"> </span>}
}

2. Code presentation

(1) The code for managing Session using ThreadLocal mode (thread local variable mode) is as follows:


<span style="font-family:System;font-size:14px;">package com.lc.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
 *  Upgraded MySessionFactory  Thread local mode 
 * @author xuliugen
 */
public class HibernateUtil {
 private static SessionFactory sessionFactory = null;
 //  Use thread local mode 
 private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
 /*
 *  Default constructor 
 */
 private HibernateUtil() {
 }
 /*
 *  Static code block 
 */
 static {
 sessionFactory = new Configuration().configure().buildSessionFactory();
 }
 /*
 *  Get a brand new session
 */
 public static Session openSession() {
 return sessionFactory.openSession();
 }
 /*
 *  Object associated with the thread session
 */
 public static Session getCurrentSession() {
 Session session = threadLocal.get();
 //  Judge whether to get it or not 
 if (session == null) {
  session = sessionFactory.openSession();
  //  Put session Put  threadLocal , equivalent to the session Already bound to a thread 
  threadLocal.set(session);
 }
 return session;
 }
}</span>

(2) The test code is as follows:


<span style="font-family:System;font-size:14px;">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
  *  The result is two hashCode Yes 1 Sample, proving to be thread-dependent 
  */
 }
}</span><span style="font-family:System;font-size:14px;">
</span>

Summarize


Related articles: