您的位置:首页 > 编程语言 > Java开发

Java ThreadLocal示例及使用方法总结

2012-03-01 10:48 891 查看
一、概述

ThreadLocal的名称比较容易让人误解,会认为其是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量。

其设计的初衷是为了解决多线程编程中的资源共享问题。提起这个,大家一般会想到synchronized,synchronized采取的是“以时间换空间”的策略,本质上是对关键资源上锁,让大家排队操作。而ThreadLocal采取的是“以空间换时间”的思路,为每个使用该变量的线程提供独立的变量副本,在本线程内部,它相当于一个“全局变量”,可以保证本线程任何时间操纵的都是同一个对象。

二、实例

下面用一个实例阐述ThreadLocal的使用方法

创建一个Context类,其中含有transactionId属性。

package com.vigar;

public class Context {

private String transactionId = null;

public String getTransactionId() {
return transactionId;
}

public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
}


创建MyThreadLocal做为容器,将一个Context对象保存于ThreadLocal中

package com.vigar;

public class MyThreadLocal {
public static final ThreadLocal userThreadLocal = new ThreadLocal();
public static void set(Context user) {
userThreadLocal.set(user);
}

public static void unset() {
userThreadLocal.remove();
}

public static Context get() {
return (Context)userThreadLocal.get();
}
}


多线程客户端程序,用于测试

package com.vigar;

import java.util.Random;

public class ThreadLocalDemo extends Thread {

public static void main(String[] args) {
Thread threadOne = new ThreadLocalDemo();
threadOne.start();
Thread threadTwo = new ThreadLocalDemo();
threadTwo.start();
}

@Override
public void run() {
// 线程
Context context = new Context();
Random random = new Random();
int age = random.nextInt(100);
context.setTransactionId(String.valueOf(age));

System.out.println("set thread ["+getName()+"] contextid to " + String.valueOf(age));
// 在ThreadLocal中设置context
MyThreadLocal.set(context);
/* note that we are not explicitly passing the transaction id */
try {
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}

new BusinessService().businessMethod();
MyThreadLocal.unset();
}
}


模拟业务层,在某处读取context对象

package com.vigar;
public class BusinessService {
public void businessMethod() {
Context context = MyThreadLocal.get();
System.out.println(context.getTransactionId());
}
}


程序输出:

set thread [Thread-0] contextid to 32
set thread [Thread-1] contextid to 89
32
89


三、总结
ThreadLocal使用步骤

1.建立ThreadLocal容器对象A,其中对需要保存的属性进行封装。并提供相应的get/set方法(全部为static)

2.在客户端程序中,用A.setxxx, A.getXXX访问相应数据,即可保证每个线程访问的是自己独立的变量


参考文献:

1. http://lavasoft.blog.51cto.com/62575/51926/

2. http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: