`

thread local

    博客分类:
  • java
阅读更多
   在利用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,毕竟我们不能仅仅考虑今天为自己做什么,还应该考虑明天为自己做什么!
分享到:
评论

相关推荐

    tls.rar_TLS_Thread Local Storage_thread local

    在IT领域,线程本地存储(TLS,Thread Local Storage)是一种编程技术,它允许程序为每个线程维护独立的数据副本。这种技术在多线程环境中非常有用,因为它避免了数据竞争,提高了并发性能,同时也提供了数据隔离。...

    TLS_TEST.rar_TLS_Thread Local Storage

    标题“TLS_TEST.rar_TLS_Thread Local Storage”涉及到的是关于网络安全中的Transport Layer Security(TLS)协议以及在编程中的Thread Local Storage(TLS)概念。TLS是互联网上用于保护数据传输的安全标准,而...

    [并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例]

    【并发并行】_【C/C++]_【使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例】 在多线程编程中,线程本地存储(Thread Local Storage,简称TLS)是一种用于存储线程私有数据的技术。每个线程都有...

    transmittable-thread-local,

    【标题】"transmittable-thread-local" 是一个开源项目,主要关注的是线程局部变量(Thread Local)的可传递性问题。在Java编程语言中,线程局部变量是一种特殊类型的变量,它为每个线程提供独立的实例,确保了线程...

    transmittable-thread-local-2.12.1-API文档-中文版.zip

    赠送jar包:transmittable-thread-local-2.12.1.jar; 赠送原API文档:transmittable-thread-local-2.12.1-javadoc.jar; 赠送源代码:transmittable-thread-local-2.12.1-sources.jar; 赠送Maven依赖信息文件:...

    TLS.rar_Thread Local Storage

    线程局部存储(thread-local storage, TLS)是一个使用很方便的存储线程局部数据的系统。利用TLS机制可以为进程中所有的线程关联若干个数据,各个线程通过由TLS分配的全局索引来访问与 自己关联的数据。这样,每个...

    transmittable-thread-local-2.12.2-API文档-中文版.zip

    赠送jar包:transmittable-thread-local-2.12.2.jar; 赠送原API文档:transmittable-thread-local-2.12.2-javadoc.jar; 赠送源代码:transmittable-thread-local-2.12.2-sources.jar; 赠送Maven依赖信息文件:...

    transmittable-thread-local-2.12.1-API文档-中英对照版.zip

    赠送jar包:transmittable-thread-local-2.12.1.jar; 赠送原API文档:transmittable-thread-local-2.12.1-javadoc.jar; 赠送源代码:transmittable-thread-local-2.12.1-sources.jar; 赠送Maven依赖信息文件:...

    c++ thread

    6. **线程局部存储(Thread Local Storage, TLS)** 使用`thread_local`关键字,可以在每个线程中创建独立的数据副本,避免了线程间的数据共享问题。在`Message.h`中,可能用`thread_local`为每个线程维护独立的...

    C++_thread.zip

    - **线程局部存储(Thread Local Storage, TLS)**:`std::thread_local`关键字可以创建线程局部变量,每个线程拥有独立的副本。 - **未来(Future)和承诺(Promise)**:`std::future`和`std::promise`提供了一...

    linux-thread.rar_linux multi thread_linux thread_thread_thread l

    10. **线程局部存储**:线程局部存储(TLS,Thread Local Storage)允许每个线程拥有自己的变量副本,避免了线程间的数据冲突。`pthread_getspecific()`和`pthread_setspecific()`函数用于访问和设置线程局部存储。 ...

    c++ std thread的用法教程

    - **线程局部存储(TLS, Thread Local Storage)**:可以使用`thread_local`关键字为每个线程创建独立的存储空间。 8. **学习资源**: - `std--thread(线程)_傻月菇凉的博客-CSDN博客`和`C++11 mutex方便的自...

    C++ Boost Thread 编程指南

    为了保持线程之间的独立性,Boost线程库引入了线程局部存储(TLS,Thread Local Storage)的概念。TLS允许每个线程拥有自己的数据副本,即使这些数据是在全局作用域中声明的。这种方式避免了线程之间因共享数据而...

    class_thread.zip_window thread_windows多线程源码

    此外,Windows还提供了线程局部存储(TLS,Thread Local Storage),允许每个线程拥有自己的变量副本,避免了多线程环境中的数据共享问题。可以使用`TlsAlloc`分配TLS索引,然后通过`TlsSetValue`和`TlsGetValue`...

    libevent-thread-20140224-1.7z

    1. **线程局部存储(Thread Local Storage)**:Libevent可能使用TLS来存储线程特有的数据,如事件基或配置信息,以避免在多线程环境中的冲突。 2. **回调函数的执行**:在多线程环境下,回调函数的执行需要确保...

    C++_Boost_Thread_编程指南

    线程局部存储(Thread Local Storage,TLS)使得每个线程可以拥有自己独立的变量副本,即使这些变量在全局或静态作用域内。`boost::thread_specific_ptr`是Boost库提供的一个工具,用于管理线程特有的指针,防止内存...

    ThreadLocal:可移植和实现可配置的c ++ 11,例如线程本地

    线程本地 可移植,实现可配置,... 宏THREAD_LOCAL(...)的默认实现是c ++ 11 thread_local关键字(如果支持)。 否则,将使用pthread和FLS实现。 为什么 c++11 thread_local不适用于vs2013,macOS &lt;10&gt; )必须具有静态

    C++ 线程学习,thread常用操作

    5. **线程局部存储(Thread Local Storage, TLS)** - 使用`thread_local`关键字可以声明线程局部变量,每个线程都有自己独立的一份副本,不会互相干扰。 6. **线程池** - 线程池是一种优化策略,预先创建一组...

    thread_thread_

    5. **线程局部存储**:线程局部存储(Thread Local Storage,TLS)允许每个线程拥有自己的变量副本,避免了多线程环境下的数据冲突。 6. **线程池**:为管理大量线程,可以使用线程池。线程池预先创建一定数量的...

    thread.rar

    5. **线程局部存储(TLS, Thread Local Storage)** 使用`thread_local`关键字,可以声明一个变量为线程局部,每个线程拥有该变量的独立实例。 6. **线程安全** 在多线程环境下,不是所有操作都是线程安全的。...

Global site tag (gtag.js) - Google Analytics