Java ThreadLocal类学习

ThreadLocal为线程局部变量,通过线程名(key)-对象(value)的Map来获取每个线程对应的对象。我们不能通过ThreadLocal处理多线程并发问题,但是每个线程可以通过ThreadLocal轻易的访问到自己保存的对象。

以Hibernate中sessionFactory,Session举例

	在Hibernate中sessionFactory是线程安全,在web应用中只要有一份实例就行,但是Session是每个线程都各自拥有一份实例,不然不同的线程持有同一个session对象进行CRUD,会引起数据操作混乱。因此为每一个线程都分配一个独自的Session实例,这里可以应用了ThreadLocal。下面进行简单模拟,说明ThreadLocal使用
//SessioinFactory类保存一个自定义的ThreadLocalSessionContext对象
package com.localthread;

public class SessionFactory {
	public ThreadLocalSessionContext sc;
	public SessionFactory(){
		sc= new ThreadLocalSessionContext(this);
	}
	public Session currentSession(){
		return sc.currentSession();
	}
	public Session createSession(){
		return new Session();
	}
}

package com.localthread;

import java.util.HashMap;
import java.util.Map;
//使用ThreadLocal来保存一个以SessionFactory-Session为key-value的Map。
public class ThreadLocalSessionContext {
	private SessionFactory sessionFactory;
	public ThreadLocalSessionContext(SessionFactory sessionFactory){this.sessionFactory=sessionFactory;}
	public SessionFactory factory(){return sessionFactory;}
	private static final ThreadLocal<Map> CONTEXT_TL=new ThreadLocal();//应用ThreadLocal,其中的Map的SessionFactory(key)-Session(value)
	//获得当前线程的Session,没有则用SessioinFactory创建一个
	public final Session currentSession(){
		Session session=exsitSession(factory());
		if(session==null){
			 session=factory().createSession();
			bind(factory(),session);
		}	
		return session;
	}
	public static Map sessionMap(){
		return CONTEXT_TL.get();
	}
	public static Session exsitSession(SessionFactory factory){
		Map sessionMap=sessionMap();
		if(sessionMap==null)
			return null;
		return (Session) sessionMap.get(factory);
	}
	public static void bind(SessionFactory factory,Session session){
		Map sessionMap=sessionMap();
		if(sessionMap==null){
			sessionMap=new HashMap();
			CONTEXT_TL.set(sessionMap);
		}
			
		sessionMap.put(factory, session);
	}
}
package com.localthread;
//打印sessionId
public class Session {
	public int sessionId=0;
	public void print(){
		System.out.println(Thread.currentThread().getName()+":"+this+",sessionId:"+sessionId++);
	}
}
//测试类
/***

启动三个线程共享一个SessionFactory,在每个线程的Run方法中获得每个线程各自对应的Session,测试输出如下图:
其中SessionId++按照预期运行。
**/
package com.localthread;

public class Main {
	public static void main(String[] args) {
		SessionFactory factory=new SessionFactory();
		SessionThread s1=new SessionThread(factory);
		SessionThread s2=new SessionThread(factory);
		SessionThread s3=new SessionThread(factory);
		s1.start();s2.start();s3.start();
	}
}
 class SessionThread extends Thread{
	 private int count=5;
	 private SessionFactory factory;
	 public SessionThread(SessionFactory factory){
		 this.factory=factory;
	 }
	 public void run(){
		 while(count>0){
			 factory.currentSession().print();
			 count--;
		 }
	 }
 }

执行结果:

posted @ 2017-06-26 12:00  不被女生喜欢好多年  阅读(194)  评论(0编辑  收藏  举报