用法一:在关联数据类中创建private static ThreadLocal
ThreaLocal的JDK文档中说明:ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread。如果我们希望通过某个类将状态(例如用户ID、事务ID)与线程关联起来,那么通常在这个类中定义private static类型的ThreadLocal?实例。
?
例如,在下面的类中,私有静态?ThreadLocal?实例(serialNum)为调用该类的静态?SerialNum.get()?方法的每个线程维护了一个“序列号”,该方法将返回当前线程的序列号。(线程的序列号是在第一次调用?SerialNum.get()?时分配的,并在后续调用中不会更改。)
?
- 1999998092651px; margin-bottom: 0px !important; margin-left: 0px !important; padding-right: 3px !important; padding-left: 10px !important;" class="alt">public?class?SerialNum?{??
- ??????
- ????private?static?int?nextSerialNum?=?0;??
- ??
- ????private?static?ThreadLocal?serialNum?=?new?ThreadLocal()?{??
- ????????protected?synchronized?Object?initialValue()?{??
- ????????????return?new?Integer(nextSerialNum++);??
- ????????}??
- ????};??
- ??
- ????public?static?int?get()?{??
- ????????return?((Integer)?(serialNum.get())).intValue();??
- ????}??
- }??
?
【例】
?
public?
class?
ThreadContext?{
?
? private?String userId;
? private?Long transactionId;
?
? private?
static?
ThreadLocal?threadLocal?
=?
new?ThreadLocal(){
?? ?@Override
????????
protected?ThreadContext?
initialValue() {
????????????
return?
new?ThreadContext();
????????}
?
? };
? public?
static?ThreadContext?
get() {
????
return?threadLocal.get();
? }
? public?String getUserId() {
????
return?userId;
? }
? public?
void?setUserId(String userId) {
????
this.userId?
=?userId;
? }
? public?Long getTransactionId() {
????
return?transactionId;
? }
? public?
void?setTransactionId(Long transactionId) {
????
this.transactionId?
=?transactionId;
? }
?
}
?
用法二:在Util类中创建ThreadLocal
这是上面用法的扩展,即把ThreadLocal的创建放到工具类中。
【例】例如Hibernate的工具类:
public?
class?HibernateUtil {
????
private?
static?Log log?
=?LogFactory.getLog(HibernateUtil.
class);
????
private?
static?
final?SessionFactory sessionFactory;?????
//定义SessionFactory?
????
static?{
????????
try?{
????????????
// 通过默认配置文件hibernate.cfg.xml创建SessionFactory????????????sessionFactory?
=?
new?Configuration().configure().buildSessionFactory();
????????}?
catch?(Throwable ex) {
????????????log.error(
"初始化SessionFactory失败!", ex);
????????????
throw?
new?ExceptionInInitializerError(ex);
????????}
????}
????
//创建线程局部变量session,用来保存Hibernate的Session???
?public?static?final?ThreadLocal?session?
=?
new?ThreadLocal();
?
????
/**
?????* 获取当前线程中的Session
?????* @return Session
?????* @throws HibernateException
?????*/????
public?
static?Session?
currentSession()?
throws?HibernateException {
????????Session s?
=?(Session) session.get();
????????
// 如果Session还没有打开,则新开一个Session????????
if?(s?
==?null) {
????????????s?
=?sessionFactory.openSession();
????????????session.set(s);?????????
//将新开的Session保存到线程局部变量中????????}
????????
return?s;
????}
?
????
public?
static?
void?closeSession()?
throws?HibernateException {
????????
//获取线程局部变量,并强制转换为Session类型????????Session s?
=?(Session) session.get();
????????session.set(null);
????????
if?(s?
!=?null)
????????????s.close();
????}
}
?
?
用法三:在Runnable中创建ThreadLocal
?还有一种用法是
在线程类内部创建ThreadLocal,基本步骤如下:
1、在多线程的类(如ThreadDemo类)中,创建一个ThreadLocal对象threadXxx,用来保存线程间需要隔离处理的对象xxx。?
2、在ThreadDemo类中,创建一个获取要隔离访问的数据的方法getXxx(),在方法中判断,若ThreadLocal对象为null时候,应该new()一个隔离访问类型的对象,并强制转换为要应用的类型。?
3、在ThreadDemo类的run()方法中,通过调用getXxx()方法获取要操作的数据,这样可以保证每个线程对应一个数据对象,在任何时刻都操作的是这个对象。
?
?
?
public?
class?ThreadLocalTest?
implements?Runnable{
????
????
ThreadLocal<Studen>?studenThreadLocal?
=?
new?ThreadLocal
<Studen
>();
????@Override
????
public?
void?run() {
????????String currentThreadName?
=?Thread.currentThread().getName();
????????System.out.println(currentThreadName?
+?
" is running...");
????????Random random?
=?
new?Random();
????????
int?age?
=?random.nextInt(
100);
????????System.out.println(currentThreadName?
+?
" is set age: "??
+?age);
????????Studen studen?
=?
getStudent();?
//通过这个方法,为每个线程都独立的new一个student对象,每个线程的的student对象都可以设置不同的值????????studen.setAge(age);
????????System.out.println(currentThreadName?
+?
" is first get age: "?
+?studen.getAge());
????????
try?{
????????????Thread.sleep(
500);
????????}?
catch?(InterruptedException e) {
????????????e.printStackTrace();
????????}
????????System.out.println( currentThreadName?
+?
" is second get age: "?
+?studen.getAge());
????????
????}
????
????
private?Studen?
getStudent() {
????????Studen studen?
=?studenThreadLocal.get();
????????
if?(null?
==?studen) {
????????????studen?
=?
new?Studen();
????????????studenThreadLocal.set(studen);
????????}
????????
return?studen;
????}
????
public?
static?
void?main(String[] args) {
????????ThreadLocalTest t?
=?
new?ThreadLocalTest();
????????Thread t1?
=?
new?Thread(t,
"Thread A");
????????Thread t2?
=?
new?Thread(t,
"Thread B");
????????t1.start();
????????t2.start();
????}
????
}
class?Studen{
????
int?age;
????
public?
int?getAge() {
????????
return?age;
????}
????
public?
void?setAge(
int?age) {
????????
this.age?
=?age;
????}
????
}
?
?
?
?
转自:http://blog.csdn.net/vking_wang/article/details/14225379