本文概览:介绍了ThreadLocal在项目中使用场景、编码和一些总结。
1 场景和代码
1. 场景
不同线程对于同一个变量独享一份
有时候在一个线程中有多个函数,在这些函数中都需要用到某一个变量的值,但是又不方便通过参数来传递
2. 代码
(1)context
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/** * 相当于一个Bean */ public class Context { String threhold; String productNo; public String getThrehold() { return threhold; } public void setThrehold(String threhold) { this.threhold = threhold; } public String getProductNo() { return productNo; } public void setProductNo(String productNo) { this.productNo = productNo; } } |
(2)ContextHolder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/** * 可以理解为一个utils的工具类,所以成员都是static类型. */ public class ContextHolder { private static final ThreadLocal<Context> contextStore = new ThreadLocal<Context>(); /** * 获取上下文 * * @return */ public static Context getContext() { Context context = contextStore.get(); // 没有保存上下文,则返回对象 if (context == null) { contextStore.set(new Context()); return contextStore.get(); } return context; } /** * 设置上下文 * * @param context */ public static void setContext(Context context) { contextStore.set(context); } /** * 清空 */ public static void clear() { contextStore.remove(); } } |
(3)TestContextHolder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class TestContextHolder { public static void main(String[] args) { // 1.主线程 Context context = new Context(); context.setProductNo("9100032"); context.setThrehold("100"); ContextHolder.setContext(context); Thread thread1 = new Thread(new Runnable() { public void run() { System.out.println("在新的线程中获取context的值为,productNo="+ ContextHolder.getContext().getProductNo()+";threhold="+ContextHolder.getContext().getThrehold()); } }); // 1.启动新线程 thread1.start(); // 2.来主线程获取 System.out.println("在主线程中获取context的值为,productNo="+ ContextHolder.getContext().getProductNo()+";threhold="+ContextHolder.getContext().getThrehold()); } } |
2 一些总结
1. 总结1 理解context和contextHolder。
- context相当于bean。可以是自己定义的一个Bean类型,有时候也可以是Map类型、String类型等基本类型。
- contextHolder都是static方法。
2. 总结2 在ContextHolder只能在同一个线程中有效。
如上代码中,在新线程中,打印的结果都是null。
1 2 |
在主线程中获取context的值为,productNo=9100032;threhold=100 在新的线程中获取context的值为,productNo=null;threhold=null |
(全文完,后续看下ThreadLocal源码实现)