Hibernate ThreadLocal
它会为每个线程维护一个私有的变量空间。实际上, 其实现原理是在JVM 中维护一个Map,这个Map的key 就是当前的线程对象,而value则是 线程通过Hibernate ThreadLocal.set方法保存的对象实例。当线程调用Hibernate ThreadLocal.get方法时, Hibernate ThreadLocal会根据当前线程对象的引用,取出Map中对应的对象返回。
这样,Hibernate ThreadLocal通过以各个线程对象的引用作为区分,从而将不同线程的变量隔离开来。
一、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 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>} }
二、代码的展示
(1)使用ThreadLocal模式 (线程局部变量模式) 管理Session的代码如下:
<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; /** * 升级的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 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 * 结果是两个hashCode是一样的,证明是线程相关的 */ } }</span><span style="font-family:System;font-size:14px;"> </span>
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对小牛知识库的支持。如果你想了解更多相关内容请查看下面相关链接
问题内容: 我想以“程序化”方式定义全局变量。与我要执行的操作类似的操作是: 具体来说,我想创建一个包含可通过诸如此类访问的变量的模块,其中所有值都是通过解析文件获得的(因此需要以“编程”方式进行分配)。 现在,以上解决方案将起作用。但是我对此有些不安,因为恐怕这不是实现设置模块全局变量的最干净的方法。 问题答案: 您可以在globals()返回的字典中设置globals:
环境变量 Vite 在一个特殊的 import.meta.env 对象上暴露环境变量。这里有一些普遍适用的内建变量: import.meta.env.MODE: string 应用运行基于的 模式。 import.meta.env.BASE_URL: string 应用正被部署在的 base URL。它由 base 配置项 决定。 import.meta.env.PROD: boolean 应用是
你可以替换你的项目根目录中的下列文件来指定环境变量: .env # 在所有的环境中被载入 .env.local # 在所有的环境中被载入,但会被 git 忽略 .env.[mode] # 只在指定的模式中被载入 .env.[mode].local # 只在指定的模式中被载入,但会被 git 忽略 一个环境文件只包含环境变量的“键
问题内容: 我定义了一个.dir-locals.el文件,其内容如下: 在我的.emacs中,我具有以下函数来检索此值并提供virtualenv路径: 最后,在我的python-mode-hook列表中,我具有以下hook函数: 当我打开一个新的python文件时,记录的消息表明是。但是,当我Ch v名称时,我得到的是“ saas”。 显然,这里存在装载订单问题;有没有办法让我的模式钩子语句响应目
问题内容: 有没有办法在CSS中设置全局变量,例如: 问题答案: 最新更新:16/01/2020 CSS自定义属性(变量)已经到来!到了2020年,是时候正式在您的新产品中推出此功能了 应用程序。 需要预处理器“ NOT”! CSS中有很多重复。可以在多个地方使用一种颜色。 对于某些CSS声明,可以在级联中声明更高的位置,并让CSS继承自然解决此问题。 对于非平凡的项目,这并不总是可能的。通过在:
我有一个类需要测试。以下是的定义: 并根据值从数据库中检索一些要操作的数据。对于该数据库,值通过JSON文件持久化。 这使事情复杂化了。我需要的是在测试时将其设置为某个特定的日期。有没有办法可以用mockito模拟局部变量的值?