Java多线程17 使用ThreadLocal重新设计一个上下文
2019-01-28 本文已影响17人
香沙小熊
public class Context {
private String name;
private String cardId;
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
public class ExecutionTask implements Runnable {
private QueryFromDBAction queryAction = new QueryFromDBAction();
private QueryFromHttpAction httpAction = new QueryFromHttpAction();
@Override
public void run() {
final Context context = new Context();
queryAction.execute(context);
System.out.println("The name query successful");
httpAction.execute(context);
System.out.println("The cardId query successful");
System.out.println("The Name is " + context.getName() + " and CardId " + context.getCardId());
}
}
public class QueryFromDBAction {
public void execute(Context context) {
try {
Thread.sleep(1000L);
String name = "Jack " + Thread.currentThread().getName();
context.setName(name);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void execute(Context context) {
String name = context.getName();
String cardId = getCardId(name);
context.setCardId(cardId);
}
private String getCardId(String name) {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "444555" + Thread.currentThread().getId();
}
}
public class ContextTest {
public static void main(String[] args) {
IntStream.range(1, 5)
.forEach(i ->
new Thread(new ExecutionTask()).start()
);
}
}
The name query successful
The name query successful
The name query successful
The name query successful
The cardId query successful
The Name is Jack Thread-0 and CardId 44455511
The cardId query successful
The Name is Jack Thread-1 and CardId 44455512
The cardId query successful
The Name is Jack Thread-2 and CardId 44455513
The cardId query successful
The Name is Jack Thread-3 and CardId 44455514
问题:需要在每个调用Context的方法中传入进去
public void execute(Context context) {
}
使用ThreadLocal重新设计一个上下文设计模式
public final class ActionContext {
private static final ThreadLocal<Context> threadLocal = new ThreadLocal() {
@Override
protected Object initialValue() {
return new Context();
}
};
public static ActionContext getActionContext() {
return ContextHolder.actionContext;
}
public Context getContext() {
return threadLocal.get();
}
private static class ContextHolder {
private final static ActionContext actionContext = new ActionContext();
}
}
public class Context {
private String name;
private String cardId;
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
public class ExecutionTask implements Runnable {
private QueryFromDBAction queryAction = new QueryFromDBAction();
private QueryFromHttpAction httpAction = new QueryFromHttpAction();
@Override
public void run() {
queryAction.execute();
System.out.println("The name query successful");
httpAction.execute();
System.out.println("The cardId query successful");
final Context context = ActionContext.getActionContext().getContext();
System.out.println("The Name is " + context.getName() + " and CardId " + context.getCardId());
}
}
public class QueryFromDBAction {
public void execute() {
try {
Thread.sleep(1000L);
String name = "Jack " + Thread.currentThread().getName();
ActionContext.getActionContext().getContext().setName(name);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class QueryFromHttpAction {
public void execute() {
Context context = ActionContext.getActionContext().getContext();
String name = context.getName();
String cardId = getCardId(name);
context.setCardId(cardId);
}
private String getCardId(String name) {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "444555" + Thread.currentThread().getId();
}
}
public class ContextTest {
public static void main(String[] args) {
IntStream.range(1, 5)
.forEach(i ->
new Thread(new ExecutionTask()).start()
);
}
}
The name query successful
The name query successful
The name query successful
The name query successful
The cardId query successful
The Name is Jack Thread-3 and CardId 44455514
The cardId query successful
The cardId query successful
The Name is Jack Thread-0 and CardId 44455511
The cardId query successful
The Name is Jack Thread-2 and CardId 44455513
The Name is Jack Thread-1 and CardId 44455512
这样写 执行过程中不会看到context的定义和声明