在hibernate中session是使用ThreadLocal实现线程安全的。
ThreadLocal并不是一个Thread,而是一个线程副本,ThreadLocal为每个使用该变量的线程提供一个变量副本,线程修改自己的变量副本不会影响其他线程的变量副本
ThreadLocal有四个方法:
set():设置当前线程的局部变量的值
get():获取当前线程的局部变量的值
remove():将当前线程局部变量的值删除,此方法不必显示的调用,因为局部变量自有垃圾回收器去清理
initialValue():返回该局部变量的初始值,只有在线程第一次调用get,set方法时,此方法才会执行
ThreadLocal源码如下:
public class ThreadLocal { /*这个集合中以当前线程对象作为键,值就是该线程对象的变量副本的值,也就是 * session */ Map map = Collections.synchronizedMap(new HashMap()); public Object get(){ Thread currentThread = Thread.currentThread(); Object o = map.get(currentThread); if(o == null && !map.containsKey(currentThread)){ o = initialValue(); map.put(currentThread, o); } return o; } public void set(Object newValue){ map.put(Thread.currentThread(), newValue); } public Object initialValue() { return null; } }
hibernate中的getCurrentSession()的底层代码如下:
public class CurrentSession { public static final ThreadLocal session = new ThreadLocal(); public static final SessionFactory sf; static { sf = new Configuration().configure().buildSessionFactory(); } public Session getCurrentSession(){ Session s = (Session) session.get(); if(s == null){ s = sf.openSession(); session.set(s); } return s; } }
总结:要想让多线程实现对共享资源的操纵,就需要对它进行同步处理,这不是一件容易的事,不仅会降低程序性能,还要小心死锁的产生,而ThreadLocal模式,直接让每一个线程都具有自己的一个session,他仅仅操作自己的session不会影响其它线程的session,因此也就不需要进行同步处理
时间: 2024-12-20 15:30:12