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