作者:dxaw 来源:赛迪网
在利用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,用于存储每一个线程的变量的副本。比如下面的示例实现(为了简单,没有考虑集合的泛型):
public class ThreadLocal {
private Map values = Collections.synchronizedMap(new HashMap());
public Object get() {
Thread currentThread = Thread.currentThread();
Object result = values.get(currentThread);
if(result == null&&!values.containsKey(currentThread)) {
result = initialValue();
values.put(currentThread, result);
}
return result;
}
public void set(Object newValue) {
values.put(Thread.currentThread(), newValue);
}
public Object initialValue() {
return null;
}
}
|
那麽具体如何利用ThreadLocal来管理Session呢?Hibernate官方文档手册的示例之中,提供了一个通过ThreadLocal维护Session的好榜样:
public class HibernateUtil {
public static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static final ThreadLocal<Session>session=new ThreadLocal<Session>();
public static Session currentSession() throws HibernateException {
Session s = session.get();
if(s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = session.get();
if(s != null) {
s.close();
}
session.set(null);
}
}
|
只要借助上面的工具类获取Session实例,我们就可以实现线程范围内的Session共享,从而避免了线程中频繁的创建和销毁Session实例。当然,不要忘记在用完后关闭Session。写到这里,想再多说一些,也许大多数时候我们的DAO并不会涉及到多线程的情形,比如我们不会将DAO的代码写在Servlet之中,那样不是良好的设计,我自己通常会在service层的代码里访问DAO的方法。但是我还是建议采用以上的工具类来管理Session,毕竟我们不能仅仅考虑今天为自己做什么,还应该考虑明天为自己做什么!
(责任编辑:龚勋)
分享到:
相关推荐
在Web应用中,特别是对于"session"数据的管理,ThreadLocal可以作为一种有效的解决方案。 1. **什么是Session?** Session是HTTP协议中的一个概念,用于存储用户在服务器端的状态信息。当用户登录网站后,服务器会...
【ThreadLocal模式管理Session的理解】 在使用Hibernate进行数据库操作时,正确管理Session是优化系统性能的关键。Session由SessionFactory创建,而SessionFactory是线程安全的,这意味着它可以被多个并发线程共享...
总结一下,这份资料涵盖了设计模式中的单例模式、工厂模式和代理模式,以及Java中的ThreadLocal特性。理解并熟练应用这些概念和技术,对于提升Java开发者的技能水平,优化代码的可读性和可维护性具有重要作用。在...
5. **事务管理**:在使用ThreadLocal的模式下,事务管理通常与Session绑定。每个线程内的操作在同一个Session中进行,方便控制事务边界。 6. **性能优化**:ThreadLocal提供了一种高效的Session管理方式,避免了...
ThreadLocal是Java编程语言中的一个类,用于在多线程环境中提供线程局部变量。它是一种强大且实用的工具,可以确保每个线程都拥有自己的独立变量副本,从而避免了传统共享变量带来的线程安全问题。这篇博文将深入...
使用ThreadLocal Session的一个关键好处是事务的自动管理。当开启一个新的Session时,Hibernate会隐式地开始一个事务;当Session关闭时,如果之前没有遇到异常,那么事务就会被提交;如果有异常,事务会被回滚,从而...
3. 存储数据库会话:在Spring Hibernate ORM中,ThreadLocal常用来保存数据库连接的Session,确保每个线程有自己的Session,避免线程间的资源冲突。 总之,ThreadLocal是一个强大的工具,但理解其工作原理和潜在...
- 请求上下文:在Web应用中,可以使用ThreadLocal存储HttpServletRequest、Session等与请求相关的数据,确保这些数据只在当前请求的线程内可见。 - 数据库连接:在数据库连接池中,可以使用ThreadLocal为每个线程...
ThreadLocal 相关知识点 ThreadLocal 是 Java 语言中的一种机制,用于提供线程内部的局部变量。在多线程环境下,ThreadLocal 变量可以保证各个线程的变量相对独立于其他线程内的变量。这种机制可以帮助开发者在多...
2. **请求上下文**:在Web应用中,可以使用`ThreadLocal`保存HttpServletRequest或Session对象,方便在同一个请求处理链路中访问。 3. **线程状态**:记录线程执行过程中的状态,例如事务管理、计数器等。 然而,...
在JDK 8之前,这个内部Map是`ThreadLocal.ThreadLocalMap`,而从JDK 8开始,改为了`WeakReference<ThreadLocal<?>>`和`Object`的组合,提高了内存管理效率。 **JDK 8之前的ThreadLocalMap** 在JDK 8之前,...
- **线程安全的配置对象**:在多层架构中,如Spring框架中,可以使用ThreadLocal来存储线程相关的配置信息,如数据库连接、事务管理等,确保这些对象不会被其他线程访问。 - **HTTP请求上下文**:在Web应用中,可以...
**线程局部变量(ThreadLocal)** 在Java编程中,`ThreadLocal`是...以上就是关于`ThreadLocal`及其内部类`ThreadLocalMap`的基础知识,它们在多线程编程中起到关键作用,帮助开发者实现高效、安全的线程局部变量管理。
Hibernate框架在处理数据库操作时,使用ThreadLocal来管理Session,确保每个线程都有自己独立的Session对象。这样,即使多个线程并发执行,每个线程也不会干扰其他线程的Session,避免了数据错乱的问题。例如,...
2. **生命周期管理**:需要注意的是,ThreadLocal变量不会自动被垃圾回收,因为它们并不直接持有任何实际的值,而是持有线程的引用。因此,当不再需要使用ThreadLocal时,应显式调用`remove()`方法,以防止内存泄漏...
在实际开发中,ThreadLocal常用于缓存线程相关的数据,如数据库连接、事务管理、请求上下文等。例如,数据库连接池通常会提供一个ThreadLocal的静态变量,使得每个线程都能快速获取到专属的数据库连接,提高并发性能...
本篇文章将详细探讨Hibernate中Session的管理,特别是如何利用ThreadLocal解决并发问题。 首先,SessionFactory是Hibernate的核心组件,它是一个线程安全的工厂类,用于创建Session实例。SessionFactory通常在应用...
Spring的事务管理分为两种模式: 1.编程式事务管理:通过PlatformTransactionManager接口实现,开发者需要手动调用begin、commit、rollback等方法进行事务控制。虽然灵活,但增加了代码复杂度,容易出错。 2.声明式...
以上就是关于ThreadLocal的基本概念、使用方法、生命周期管理和实际应用示例的详细解释。了解并熟练掌握ThreadLocal可以帮助我们编写出更高效、更安全的多线程代码。在Java并发编程中,ThreadLocal是一个不可或缺的...