解析ThreadLocal

Posted Fighting`

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析ThreadLocal相关的知识,希望对你有一定的参考价值。

如果定义了一个单实例的java bean,它有若干属性,但是有一个属性不是线程安全的,比如说HashMap。并且碰巧你并不需要在不同的线程中共享这个属性,也就是说这个属性不存在跨线程的意义。那么不推荐使用sychronize,可使用ThreadLocal

关键代码如下:

package cn.happy.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ThreadUtil {
        // 初始化一个ThreadLocal对象    
        private static final ThreadLocal sessionTL = new ThreadLocal(); 
        private static Configuration configuration;
        private final static SessionFactory sessionFactory;
        static {
            try {
                configuration = new Configuration().configure();
                sessionFactory = configuration.buildSessionFactory();
            } catch (Throwable ex) {
                throw new ExceptionInInitializerError(ex);
            }
        }
        public static Session currentSession() {
            //sessionTL的get()方法根据当前线程返回其对应的线程内部变量,
            //也就是我们需要的Session,多线程情况下共享数据库连接是不安全的。
            //ThreadLocal保证了每个线程都有自己的Session。
            Session session = (Session) sessionTL.get(); 
            // 如果session为null,则打开一个新的session
            if (session == null) { 
                //创建一个数据库连接对象session。
                session = sessionFactory.openSession(); 
                // 保存该数据库连接session到ThreadLocal中。
                sessionTL.set(session); 
            }
            //如果当前线程已经访问过数据库了,
            //则从sessionTL中get()就可以获取该线程上次获取过的数据库连接对象。
            return session; 
        }
        
        
        /**
         * 关闭Session
         */
        public static void closeSession(){
            Session session = (Session) sessionTL.get(); 
            sessionTL.set(null);
            session.close();
        }
}

①初始化一个ThreadLocal对象,该对象有get()、set()方法

②sessionTL的get()方法根据当前线程返回其对应的线程内部变量  也就是我们需要的Session,多线程情况下共享数据库连接是不安全的。 ThreadLocal保证了每个线程都有自己的Session。

③ 如果该线程是初次访问,session是NULL,则创建一个Session对象

④创建一个Session对象,保存该对象到ThreadLocal中

⑤ 如果当前线程已经访问过数据库,则从SessionTL中get()就可以获取该线程上次获取过得Session对象

⑥关闭Session,通过ThreadLocal类,既实现了多线程并发,同时,也实现了Singleton单例模式

 

以上是关于解析ThreadLocal的主要内容,如果未能解决你的问题,请参考以下文章

解析ThreadLocal

解析ThreadLocal

解析ThreadLocal

ThreadLocal源码解析-Java8

ThreadLocal源码解析

深入解析ThreadLocal