Context上下文主要用来从上文传播对象到下文中,他是可以跨线程的。 就是说 class A中你把一个OBJ对象存放到了上下文容器中, 然后你以后的所有线程或你以下调用的所有类中都可以从上下文容器中取出 上面再class A中存放的OBJ对象。而ThreadLocal对上下文的读写至关重要。
ThreadLocal用于保存某个线程共享变量:对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量。
1、ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。
2、ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。
3、ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。
4、ThreadLocal.initialValue: ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值。
代码实现:
Context.java
package com.gm.context;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 读写上下文
* @author gm
*
*/
public class Context implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private static Logger logger = LoggerFactory.getLogger(Context.class);
private Map<String, Object> map = new HashMap<String, Object>();
public static Context getInstance() {
Stack contexts = getContextStack();
if (contexts.empty()) {
contexts.push(new Context());
logger.info("Pressing context into context stack!");
}
//相同点:大家都返回栈顶的值。不同点:peek 不改变栈的值(不删除栈顶的值),pop会把栈顶的值删除。
return (Context) contexts.peek();
}
/**
* 获取上下文栈
* @return
*/
private static Stack<Context> getContextStack() {
Stack contexts = (Stack) ThreadLocalManager.getTranContext();
if (null == contexts) {
contexts = new Stack();
ThreadLocalManager.setTranContext(contexts);
logger.info("Create a stack and fill in ThreadLocal!");
}
return contexts;
}
public Object getObject(String key) {
return this.map.get(key);
}
public void setObject(String key, Object value) {
this.map.put(key, value);
}
}
ThreadLocal编写
ThreadLocalManager.java
package com.gm.context;
import java.util.HashMap;
import java.util.Map;
/**
* ThreadLocal管理类
* @author gm
*
*/
public class ThreadLocalManager {
/*
* ThreadLocal用于保存某个线程共享变量:对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量。
* 1、ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。
* 2、ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。
* 3、ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。
* 4、ThreadLocal.initialValue: ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法
*/
public static ThreadLocal<Map<String, Object>> LOCAL = new ThreadLocal<Map<String, Object>>() {
protected Map<String, Object> initialValue() {
return new HashMap<String, Object>();
}
};
public static final String GM_UID_KEY = "GM_UID";
public static final String TRAN_CONTEXT_KEY = "TRAN_CONTEXT";
public static <T> void setTranContext(T tranContext) {
((Map<String, Object>) LOCAL.get()).put(TRAN_CONTEXT_KEY, tranContext);
}
public static <T> T getTranContext() {
return (T) ((Map) LOCAL.get()).get(TRAN_CONTEXT_KEY);
}
public static void put(String key, Object vlaue) {
((Map<String, Object>) LOCAL.get()).put(key, vlaue);
}
public static Object get(String key) {
return ((Map<String, Object>) LOCAL.get()).get(key);
}
public static Map<String, Object> getALlInfo() {
return (Map<String, Object>) LOCAL.get();
}
public static void remove() {
LOCAL.remove();
}
}
测试
package com.gm.context;
import java.util.ArrayList;
import java.util.List;
public class ContextTest {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Context.getInstance().setObject("list", list);
System.out.println(Context.getInstance().getObject("list"));
}
}
执行后的日志: