在利用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管理方式,避免了...
Hibernate框架在处理数据库操作时,使用ThreadLocal来管理Session,确保每个线程都有自己独立的Session对象。这样,即使多个线程并发执行,每个线程也不会干扰其他线程的Session,避免了数据错乱的问题。例如,...
3. 存储数据库会话:在Spring Hibernate ORM中,ThreadLocal常用来保存数据库连接的Session,确保每个线程有自己的Session,避免线程间的资源冲突。 总之,ThreadLocal是一个强大的工具,但理解其工作原理和潜在...
以上就是关于ThreadLocal的基本概念、使用方法、生命周期管理和实际应用示例的详细解释。了解并熟练掌握ThreadLocal可以帮助我们编写出更高效、更安全的多线程代码。在Java并发编程中,ThreadLocal是一个不可或缺的...
Spring的事务管理分为两种模式: 1.编程式事务管理:通过PlatformTransactionManager接口实现,开发者需要手动调用begin、commit、rollback等方法进行事务控制。虽然灵活,但增加了代码复杂度,容易出错。 2.声明式...
1. **数据库连接管理**:如上文的Hibernate示例,通过`ThreadLocal`管理每个线程的数据库连接,确保每个线程拥有独立的连接资源,避免了资源竞争。 2. **事务处理**:在事务管理中,`ThreadLocal`可以用于维护每个...
ThreadLocal是Java编程语言中的一个类,用于在多线程环境中提供线程局部变量。...合理的使用能够帮助我们编写出更高效、更易于维护的多线程程序,但也要避免滥用,因为它可能会引入难以察觉的并发问题和内存管理问题。
ThreadLocal自JDK 1.2起就存在,它不是一个线程,而是一种管理线程局部变量的机制。每个线程都有其独立的ThreadLocal变量副本,这样每个线程都可以独立地修改自己的副本而不影响其他线程。这有助于避免并发问题,...
本篇文章将详细探讨Hibernate中Session的管理,特别是如何利用ThreadLocal解决并发问题。 首先,SessionFactory是Hibernate的核心组件,它是一个线程安全的工厂类,用于创建Session实例。SessionFactory通常在应用...
在Spring事务管理中,ThreadLocal被用来存储当前线程的事务信息,例如事务隔离级别、是否回滚等。这样,Spring可以在事务范围内正确地传播事务,即使在多线程环境下也能保证事务的正确性。 在Spring的`...
ThreadLocal常用于保存线程上下文信息,如用户Session、数据库连接、事务ID等,确保这些信息只在当前线程内有效。 2. **避免同步:** 如果多个线程需要访问相同的数据,但是每个线程都需要自己的副本,...
在Java编程领域,ThreadLocal和事务管理是两个关键的概念,特别是在构建复杂且高效的Web应用程序时。ThreadLocal是一种线程局部变量,而事务则是数据库操作的原子性保证。在这个小型简单练习中,我们看到如何结合c3p...
当Java事务与ThreadLocal结合使用时,可以在不同的线程中维护各自的事务状态,比如在Spring框架中,每个线程的ThreadLocal可以存储一个TransactionStatus对象,这样就可以在线程内部管理当前事务的状态,而不会影响...
- 请求上下文:在Web应用中,可以使用ThreadLocal存储HttpServletRequest、Session等与请求相关的数据,确保这些数据只在当前请求的线程内可见。 - 数据库连接:在数据库连接池中,可以使用ThreadLocal为每个线程...
理解ThreadLocal 理解ThreadLocal 理解ThreadLocal 理解ThreadLocal