线程安全保险箱 ThreadLocal(现在ThreadLocal用的Map保存数据(ThreadLocalMap),在以前版本用的是一个数组去保存,一个保存key,后一个保存value,现在改变了存储方式)
它是线程的局部变量,这些变量只能在这个线程内被读写,在其他线程内是无法访问的。 ThreadLocal 定义的通常是与线程关联的私有静态字段
ThreadLocal
使用以当前线程作为Key值
使用场景:
在线程中使用,避免使用参数,
public interface Action {
void execute();
}
public class QueryFromDBAction implements Action{
@Override
public void execute() {
try {
Thread.sleep(1000);
ActionContext.getInstance().getContext().setName("Hello " + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class QueryFromHttpAction implements Action {
@Override
public void execute() {
Context context = ActionContext.getInstance().getContext();
try {
Thread.sleep(1000);
context.setCardID("1234567890 " + context.getName() +" "+ Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ExecuteTask implements Runnable {
Action dbAction = new QueryFromDBAction();
Action httpAction = new QueryFromHttpAction();
@Override
public void run() {
dbAction.execute();
httpAction.execute();
Context context = ActionContext.getInstance().getContext();
System.out.println("name is " + context.getName() + " cardId is " + context.getCardID());
}
}
public class ActionContext {
private ThreadLocal<Context> contextThreadLocal = ThreadLocal.withInitial(Context::new);
private ActionContext(){}
public static ActionContext getInstance(){
return ActionHolder.actionContext;
}
private static class ActionHolder{
private static ActionContext actionContext = new ActionContext();
}
public Context getContext(){
return contextThreadLocal.get();
}
}
public class Context {
private String name;
private String CardID;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCardID() {
return CardID;
}
public void setCardID(String cardID) {
CardID = cardID;
}
}
public class ThreadLocalTest {
public static void main(String[] args){
IntStream.range(1,5).forEach((i)->new Thread(new ExecuteTask()).start());
}
}