hibernate——通过ThreadLocal维护线程

为什么使用TreadLocal来实现? 

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 

具体实现如下: 

创建com.util.HibernateUtil.java

package com.util;

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

public class HibernateUtil {
	public HibernateUtil() {
	}
	private static final String RESOURCE = "resource/hibernate.cfg.xml";
	private static SessionFactory sessionFactory = null;
	private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

	static {
		try {
			Configuration cfg = new Configuration().configure(RESOURCE);
			sessionFactory = cfg.buildSessionFactory();
		} catch (Exception e1) {
			e1.printStackTrace();
			throw new ExceptionInInitializerError("初始化hibernate错误,请检查配置文件或数据库");

		}
	}

	public static SessionFactory getSqlSessionFactory() {
		return sessionFactory;
	}

	public static Session getSession() {
		// sessionTL的get()方法根据当前线程返回其对应的线程内部变量,
		// 也就是我们需要的Session,多线程情况下共享数据库链接是不安全的。
		// ThreadLocal保证了每个线程都有自己的Session。
		Session session = threadLocal.get();
		// 如果session为null,则打开一个新的session
		if (session == null) {
			session = (sessionFactory != null) ? sessionFactory.openSession() : null;
			threadLocal.set(session);
		}
		return session;
	}

	public static void closeSession() {
		Session session = (Session) threadLocal.get(); 
		threadLocal.set(null);
		if (session != null) {
			session.close();
		}
	}
}

接下来进行测试: 
首先创建com.test.MySession.java并继承Thread

package com.test;
import org.hibernate.Session;

import com.util.HibernateUtil;

public class MySession extends Thread {
	@Override
	public void run() {
		Session session1 = HibernateUtil.getSession();
		Session session2 = HibernateUtil.getSession();
		Session session3 = HibernateUtil.getSession();
		// 输出session的hashCode,分辨是否是同一个session实例
		System.out.println(Thread.currentThread().getName() + ":\n" + 
				session1.hashCode() + "\n" + 
				session2.hashCode() + "\n"+ 
				session3.hashCode());
	}

}

创建com.test.Test.java

package com.test;

public class SessionMain {
	public static void main(String[] args) {
		Thread MyThread01 =  new MySession();
		MyThread01.setName("线程一");
		Thread MyThread02 =  new MySession();
		MyThread02.setName("线程二");
		Thread MyThread03 =  new MySession();
		MyThread03.setName("线程三");
		MyThread01.start();
		MyThread02.start();
		MyThread03.start();
	}
}

运行结果:

线程一:
484059751
484059751
484059751
线程二:
839802549
839802549
839802549
线程三:
1319519604
1319519604
1319519604


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值