在利用Hibernate开发DAO模块时,我们和Session打的交道最多,所以如何合理的管理Session,避免Session的频繁创建和销毁,对于提高系统的性能来说是非常重要的,以往是通过eclipse的插件来自动完成这些代码的,当然效果是不错的,但是总是觉得不爽(没有读懂那些冗长的代码),所以现在打算自己实现Session管理的代码。我们知道Session是由SessionFactory负责创建的,而SessionFactory的实现是线程安全的,多个并发的线程可以同时访问一个SessionFactory并从中获取Session实例,那么Session是否是线程安全的呢?很遗憾,答案是否定的。Session中包含了数据库操作相关的状态信息,那么说如果多个线程同时使用一个Session实例进行CRUD,就很有可能导致数据存取的混乱,你能够想像那些你根本不能预测执行顺序的线程对你的一条记录进行操作的情形吗?
在Session的众多管理方案中,我们今天来认识一种名为ThreadLocal模式的解决方案。
早在Java1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序时提供了一种新的选择。ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。比如下面的示例实现(为了简单,没有考虑集合的泛型):
1. public class ThreadLocal {
2. private Map values = Collections.synchronizedMap(new HashMap());
3. public Object get() {
4. Thread currentThread = Thread.currentThread();
5. Object result = values.get(currentThread);
6. if(result == null&&!values.containsKey(currentThread)) {
7. result = initialValue();
8. values.put(currentThread, result);
9. }
10. return result;
11. }
12. public void set(Object newValue) {
13. values.put(Thread.currentThread(), newValue);
14. }
15. public Object initialValue() {
16. return null;
17. }
18. }
那麽具体如何利用ThreadLocal来管理Session呢?Hibernate官方文档手册的示例之中,提供了一个通过ThreadLocal维护Session的好榜样:
1. public class HibernateUtil {
2. public static final SessionFactory sessionFactory;
3. static {
4. try {
5. sessionFactory = new Configuration().configure()
6. .buildSessionFactory();
7. } catch (Throwable ex) {
8. throw new ExceptionInInitializerError(ex);
9. }
10. }
11. public static final ThreadLocal session =
12. new ThreadLocal();
13. public static Session currentSession() throws HibernateException {
14. Session s = session.get();
15. if(s == null) {
16. s = sessionFactory.openSession();
17. session.set(s);
18. }
19. return s;
20. }
21. public static void closeSession() throws HibernateException {
22. Session s = session.get();
23. if(s != null) {
24. s.close();
25. }
26. session.set(null);
27. }
28. }
分享到:
相关推荐
总的来说,ThreadLocal模式在Hibernate中用于管理Session,解决了多线程环境下Session的共享问题,实现了线程间的隔离,提高了系统的稳定性和效率。通过合理地使用ThreadLocal,开发者可以构建出更高效、更安全的多...
ThreadLocal是Java编程中一种非常特殊的变量类型,它主要用于在多线程环境下为每个线程提供独立的变量副本,从而避免了线程间的数据共享和冲突。然而,ThreadLocal在理解和使用过程中容易产生一些误区,这里我们将...
然而,需要注意的是,长时间运行的线程或者多线程环境可能会导致Session资源泄漏。因此,应该在适当的时候关闭Session,避免内存占用过高。 在Hibernate的配置中,可以通过`current_session_context_class`属性设置...
3. **日志记录**:在多线程环境中,`ThreadLocal`可以用于维护每个线程的日志上下文,如线程ID、用户名等,便于日志信息的记录和分析。 4. **性能优化**:在某些计算密集型应用中,`ThreadLocal`可以用于缓存线程...
总结起来,"Hibernage_Session_Manager_ThreadLocal"是一个关于使用ThreadLocal在多线程环境中优化Hibernate Session管理的技术实践,通过这种方式可以提升应用程序的性能和安全性。`HibernateUtil.java`是实现这一...
ThreadLocal 是 Java 语言中的一种多线程编程机制,用于解决多线程程序的并发问题。它不是一个 Thread,而是一个 Thread 的局部变量。ThreadLocal 的出现是为了解决多线程程序中的共享变量问题。当多个线程访问同一...
总结来说,ThreadLocal是Java中解决多线程数据隔离问题的有效工具,通过为每个线程提供独立的变量副本,它能够在不引入复杂同步机制的情况下,实现线程安全的代码编写。在设计需要线程安全的类或组件时,ThreadLocal...
ThreadLocal的内部实现原理是使用Map来存储各个线程的变量副本。这个Map的键是线程对象,值是通过ThreadLocal.set方法设置的实例。当线程调用ThreadLocal.get时,会根据当前线程找到对应的值。这种方式确保了每个...
`cfg.buildSessionFactory()`则根据配置创建SessionFactory单例,SessionFactory是负责创建Session实例的工厂类,它是线程安全的,适合在多线程环境中使用。 2. **ThreadLocal Session模式** `Hibernate...
ThreadLocal 是 Java 中用于处理线程局部变量的一个重要工具,它的设计目的是为了解决多线程环境下线程间数据隔离的问题。以下是对标题和描述中所述知识点的详细说明: 1. **与 Synchronized 的区别** - `...
Java中的ThreadLocal是一种特殊的技术,它为每个线程提供了一个独立的变量副本,避免了多线程间的直接共享,从而简化了并发编程的复杂性。ThreadLocal不是一种同步机制,而是设计来解决线程间数据隔离问题的工具。 ...
- **作用**:负责创建 `Session` 实例,它是线程安全的,可以被多线程调用来获取 `Session`。 - **特点**:构造 `SessionFactory` 很耗费资源,因此大多数情况下一个应用程序只会初始化一个 `SessionFactory` 来为...
### 知识点详解:Java.lang.ThreadLocal 类 #### 一、概述 **ThreadLocal** 并非线程的一种特殊实现形式,而是一种为每个线程...理解 ThreadLocal 的工作原理和应用场景对于编写高效可靠的多线程应用程序至关重要。
2. **ThreadLocal模式**:在多线程环境下,使用ThreadLocal来管理Hibernate的Session可以避免线程安全问题。每个线程都有自己的Session实例,这样可以确保数据访问的线程安全性。 3. **静态工厂方法**:为了提高...
而`ThreadLocalSessionContext`是一种实现,它使用线程本地存储(ThreadLocal)来维护每个线程上的`Session`实例,适用于web应用中的多线程环境。 #### ConnectionProvider接口与DriverManagerConnectionProvider `...
使用 ThreadLocal 可以为每个线程提供独立的变量副本,从而避免了多线程之间的共享变量问题。这样可以提高程序的安全性和可靠性。 ThreadLocal 的使用场景 ThreadLocal 可以应用于各种需要与线程关联状态的场景,...
- **Java并发控制**:学习如何正确地使用并发工具类(如`Volatile`、`ReentrantLock`等)来构建安全的多线程应用。 - **Java异常处理**:了解Java中的异常分类以及如何有效地处理异常,对于编写健壮的应用程序至关...
2. **Session管理**:通过`ThreadLocal`线程局部变量存储同一个`Session`,确保每个DAO实例能够使用同一个会话进行数据操作,从而避免了多次打开和关闭会话带来的性能开销。 3. **事务控制逻辑**:在`invoke`方法中...