上下文设计模式简介:ThreadLocal类顾名思义可以理解为线程本地变量。也就是说如果定义了一个ThreadLocal,每个线程往这个ThreadLocal中读写是线程隔离,互相之间不会影响的。它提供了一种将可变数据通过每个线程有自己的独立副本从而实现线程封闭的机制。
使用ThreadLocal实现上下文设计模式的实现:上下文就是贯穿整个系统或者阶段生命周期的对象,其中存贮了一些系统的全局变量信息。在很多时候,单个线程的执行任务步骤非常多的时候,后面的某一步骤需要前面的输出值(责任链模式中特别多),那么需要将参数从头传递到尾,这样会特别的麻烦,并且在参数过多的情况下更加不合适,那么这个时候就需要一个上下文作为上下文进行绑定线程传递了的.java为我们提供了一个很好的容器,就是ThreadLocal的。
- Context 文本类 用来存储上下文数据.
public class Context {
private String name;
public void setId(String id) {
this.id = id;
}
private String id;
public String getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- ActionContext :用来创建ThreadLocal对象(单例模式实现)以及获取Context对象
public class ActionContext {
private static final ThreadLocal threadLocal
= new ThreadLocal(){
@Override
protected Context initialValue() {
return new Context();
}
};
private static class ContextHolder{
private final static ActionContext actionContext
= new ActionContext();
}
public static ActionContext getInstance(){
return ContextHolder.actionContext;
}
public Context getContext(){
return threadLocal.get();
}
}
- ExecutionTask: 执行任务
public class ExecutionTask implements Runnable{
private QueryFromAction queryFromAction = new QueryFromAction();
@Override
public void run() {
Context context = ActionContext.getInstance().getContext();
queryFromAction.execute();
System.out.println("The idt query success!");
System.out.println("The name is" + context.getName() +"and The IdCard is" + context.getId());
}
}
- QueryFromAction: 模式从数据库存放数据
public class QueryFromAction {
public void execute(){
try {
Thread.sleep(1000);
String name = "author" + Thread.currentThread().getName();
ActionContext.getInstance().getContext().setName(name);
}catch (Exception e){
e.printStackTrace();
}
}
}
- QueryFromHttpAction模式从其他地方拿数据
public class QueryFromHttpAction {
public void execute(){
Context context = ActionContext.getInstance().getContext();
String name = context.getName();
String id = getCardId(name);
context.setId(id);
}
public String getCardId(String name){
try {
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
return "号码:1231242155534123>>>>>" + Thread.currentThread().getId();
}
}
- 测试
public class ContextTest {
public static void main(String[] args) {
for(int i = 0; i < 5; i++){
new Thread(new ExecutionTask()).start();
}
}
}
结果:



