ThreadLocal实现线程级上下文
一.ThreadLocal测试
package com.junge.threadlocal.context; /**
* @author Administrator
*
*/
public class ThreadScopeData {
private ThreadScopeData() { } private static ThreadLocal<ThreadScopeData> threadLocal = new ThreadLocal<ThreadScopeData>(); public static ThreadScopeData getInstance() {
if (null == threadLocal.get()) {
threadLocal.set(new ThreadScopeData());
} return threadLocal.get();
} public static void main(String[] args) { new Thread(new Runnable() {
@Override
public void run() {
System.out.println(ThreadScopeData.getInstance()); }
}).start(); new Thread(new Runnable() {
@Override
public void run() {
System.out.println(ThreadScopeData.getInstance()); }
}).start();
}
}
二.对上下接口进行封装,使用方便(线程绑定不同的业务数据,线程之间的业务数据放在上下文中)
1.上下文接口ThreadContext
package com.junge.threadlocal.context; import java.util.Map; /**
* 线程上下文接口
*
* @author Administrator
*
*/
public interface ThreadContext { /**
* 保持用户名
*
* @param userName
*/
void setUserName(String userName); /**
* 获取用户名
*
* @return
*/
String getUserName(); /**
* 保持参数1
*
* @param param
*/
void setParam1(Object param); /**
* 获取参数1
*
* @return
*/
Object getParam1(); /**
* 添加参数
*
* @param key
* @param param
*/
void addParam(String key, Object param); /**
* 获取参数
*
* @param key
* @return
*/
Object getParam(String key); /**
* 获取所有添加的参数
*
* @return
*/
Map<String, Object> getAllParam();
}
2.线程上下文接口实现ThreadContextImpl
package com.junge.threadlocal.context; import java.util.HashMap;
import java.util.Map; /**
* 线程上下文接口实现
*
* @author Administrator
*
*/
public class ThreadContextImpl implements ThreadContext { private String userName; private Object param1; private Map<String, Object> paramMap; @Override
public void setUserName(String userName) {
this.userName = userName; } @Override
public String getUserName() { return this.userName;
} @Override
public void setParam1(Object param) {
this.param1 = param; } @Override
public Object getParam1() { return param1;
} /*
* (non-Javadoc)
*
* @see
* com.junge.threadlocal.context.ThreadContext#addParam(java.lang.String,
* java.lang.Object)
*/
@Override
public void addParam(String key, Object param) {
if (null == paramMap) {
paramMap = new HashMap<String, Object>();
} paramMap.put(key, param); } /*
* (non-Javadoc)
*
* @see
* com.junge.threadlocal.context.ThreadContext#getParam(java.lang.String)
*/
@Override
public Object getParam(String key) {
if (null == paramMap) {
paramMap = new HashMap<String, Object>();
}
return paramMap.get(key);
} /*
* (non-Javadoc)
*
* @see com.junge.threadlocal.context.ThreadContext#getAllParam()
*/
@Override
public Map<String, Object> getAllParam() {
if (null == paramMap) {
paramMap = new HashMap<String, Object>();
}
return paramMap;
} }
3.线程上下文助手ThreadContextHolder
/**
*
*/
package com.junge.threadlocal.context; import java.util.Map; /**
* 线程上下文助手
*
* @author Administrator
*
*/
public class ThreadContextHolder { /**
* 上下文保持对象
*/
private static ThreadLocal<ThreadContext> threadContext = new ThreadLocal<ThreadContext>(); public static void setThreadContext(ThreadContext context) {
threadContext.set(context);
} public static ThreadContext getThreadContext() {
if (null == threadContext.get()) {
threadContext.set(new ThreadContextImpl());
}
return threadContext.get();
} public static void setUserName(String userName) {
getThreadContext().setUserName(userName);
} public static String getUserName() {
return getThreadContext().getUserName();
} public static void setParam1(Object param) {
getThreadContext().setParam1(param);
} public static Object getParam1() {
return getThreadContext().getParam1();
} public static void addParam(String key, Object param) {
getThreadContext().addParam(key, param);
} public static Object getParam(String key) {
return getThreadContext().getParam(key);
} public static Map<String, Object> getAllParam() {
return getThreadContext().getAllParam();
} } 4.线程上下文测试代码
package com.junge.threadlocal.context;
public class ThreadContextHolderTest {
/**
* @param args
*/
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
ThreadContextHolder.setUserName("userName1");
ThreadContextHolder.setParam1(new Object());
ThreadContextHolder.addParam("param1", "aaaa");
System.out.println(Thread.currentThread().getName() + ":"
+ ThreadContextHolder.getUserName());
System.out.println(Thread.currentThread().getName() + ":"
+ ThreadContextHolder.getParam1());
System.out.println(Thread.currentThread().getName() + ":"
+ ThreadContextHolder.getParam("param1"));
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
ThreadContextHolder.setUserName("userName2");
ThreadContextHolder.setParam1(new Object());
ThreadContextHolder.addParam("param1", "bbbb");
System.out.println(Thread.currentThread().getName() + ":"
+ ThreadContextHolder.getUserName());
System.out.println(Thread.currentThread().getName() + ":"
+ ThreadContextHolder.getParam1());
System.out.println(Thread.currentThread().getName() + ":"
+ ThreadContextHolder.getParam("param1"));
}
}).start();
}
}
运行结果:
Thread-0:userName1
Thread-0:java.lang.Object@6e1408
Thread-0:aaaa
Thread-1:userName2
Thread-1:java.lang.Object@e53108
Thread-1:bbbb
ThreadLocal实现线程级上下文的更多相关文章
- Flask中的ThreadLocal本地线程,上下文管理
先说一下和flask没有关系的: 我们都知道线程是由进程创建出来的,CPU实际执行的也是线程,那么线程其实是没有自己独有的内存空间的,所有的线程共享进程的资源和空间,共享就会有冲突,对于多线程对同一块 ...
- 当ThreadLocal碰上线程池
ThreadLocal使用 ThreadLocal可以让线程拥有本地变量,在web环境中,为了方便代码解耦,我们通常用它来保存上下文信息,然后用一个util类提供访问入口,从controller层到s ...
- ThreadLocal解决线程安全问题
一.线程安全问题产生的原因 线程安全问题都是由全局变量及静态变量引起的 二.线程安全问题 SimpleDateFormate sdf = new SimpleDateFormat();使用sdf.pa ...
- java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程
用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程 ThreadLocal在我的笔记"关于线程同步"的第5种方式里面有介绍,这里就不多说了. ...
- ThreadLocal本地线程变量的理解
一般的Web应用划分为展现层.服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用.在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程. ...
- ThreadLocal与线程池使用的问题
感谢博主的这篇分享,见 https://www.cnblogs.com/qifenghao/p/8977378.html 在今天的面试中,突然被考官问了这个问题,当时脱口而出的是 threadloca ...
- ThreadLocal和线程同步机制对比
共同点: ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题. 区别: 在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量. 这时该变量是多个线程共享的,使用同 ...
- ThreadLocal实现线程范围的共享变量
一.如何理解线程范围内共享数据 1.static int num=0; 2.线程1访问num变量,并设置为num=2:线程2访问num变量,并设置为num=3: 3.当线程1中对象A.B.C 在访问线 ...
- 多线程篇四:ThreadLocal实现线程范围内变量共享
1.static实现线程范围内变量共享 package com.test.shareData; import java.util.Random; /** * 多线程范围内的数据共享 * @author ...
随机推荐
- 无法创建.gitignore文件,提示必须输入文件名称
If you're using Windows it will not let you create a file without a filename in Windows Explorer. It ...
- Spring 系列教程之自定义标签的解析
Spring 系列教程之自定义标签的解析 在之前的章节中,我们提到了在 Spring 中存在默认标签与自定义标签两种,而在上一章节中我们分析了 Spring 中对默认标签的解析过程,相信大家一定已经有 ...
- 使用scrollTop返回顶部
scrollTop属性表示被隐藏在内容区域上方的像素数.元素未滚动时,scrollTop的值为0,如果元素被垂直滚动了,scrollTop的值大于0,且表示元素上方不可见内容的像素宽度 由于scrol ...
- 如何烧写BIOS到SD卡里面
针对TINY6410 ADK型号 1.SD卡格式化为FAT32或者FAT格式 2.将SD卡插入USB接口的读卡器,并插在PC的USB口 3.“以管理员身份运行”SD-Flasher.exe(在tiny ...
- openssl AES加密
此代码不涉及ECB和CBC等关联加密 #include <stdio.h> #include <string.h> #include <stdlib.h> #inc ...
- 【Go】 Go 语言环境安装
安装环境/工具 1.Linux(CentOS 7.4版) 2.go1.11.2.linux-amd64.tar Go 语言环境安装 1.下载安装包 安装包下载地址为:https://golang.or ...
- ThinkPHP getBy动态查询
getBy动态查询 ThinkPHP getBy动态查询是一个魔术方法,可以根据某个字段名称动态得到对应的一条数据记录. 根据用户名(username)查询对应的用户资料记录: public func ...
- main.cpp
/*main.cpp * *The starting point of the network simulator *-Include all network header files *-initi ...
- BZOJ 1059 [ZJOI2007]矩阵游戏 (二分图最大匹配)
1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5281 Solved: 2530[Submit][Stat ...
- Java利用MethodHandle实现反射时调用super的method
一:实现 1.Base类的实现 package me.silentdoer.reflecsuper; /** * @author silentdoer * @version 1.0 * @descri ...