温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Hibernate中怎么利用ThreadLocal模式管理Session

发布时间:2021-06-11 15:35:43 来源:亿速云 阅读:145 作者:Leah 栏目:编程语言

今天就跟大家聊聊有关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有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI