一.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实现线程级上下文的更多相关文章

  1. Flask中的ThreadLocal本地线程,上下文管理

    先说一下和flask没有关系的: 我们都知道线程是由进程创建出来的,CPU实际执行的也是线程,那么线程其实是没有自己独有的内存空间的,所有的线程共享进程的资源和空间,共享就会有冲突,对于多线程对同一块 ...

  2. 当ThreadLocal碰上线程池

    ThreadLocal使用 ThreadLocal可以让线程拥有本地变量,在web环境中,为了方便代码解耦,我们通常用它来保存上下文信息,然后用一个util类提供访问入口,从controller层到s ...

  3. ThreadLocal解决线程安全问题

    一.线程安全问题产生的原因 线程安全问题都是由全局变量及静态变量引起的 二.线程安全问题 SimpleDateFormate sdf = new SimpleDateFormat();使用sdf.pa ...

  4. java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程

    用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程 ThreadLocal在我的笔记"关于线程同步"的第5种方式里面有介绍,这里就不多说了. ...

  5. ThreadLocal本地线程变量的理解

     一般的Web应用划分为展现层.服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用.在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程.       ...

  6. ThreadLocal与线程池使用的问题

    感谢博主的这篇分享,见 https://www.cnblogs.com/qifenghao/p/8977378.html 在今天的面试中,突然被考官问了这个问题,当时脱口而出的是 threadloca ...

  7. ThreadLocal和线程同步机制对比

    共同点: ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题. 区别: 在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量. 这时该变量是多个线程共享的,使用同 ...

  8. ThreadLocal实现线程范围的共享变量

    一.如何理解线程范围内共享数据 1.static int num=0; 2.线程1访问num变量,并设置为num=2:线程2访问num变量,并设置为num=3: 3.当线程1中对象A.B.C 在访问线 ...

  9. 多线程篇四:ThreadLocal实现线程范围内变量共享

    1.static实现线程范围内变量共享 package com.test.shareData; import java.util.Random; /** * 多线程范围内的数据共享 * @author ...

随机推荐

  1. UI设计教程分享:Ps合成炫酷机械姬

    本次给大家分享一个通过PS合成一个炫酷的机械姬,在这个教程里给大家展示图像的色彩处理.人物光影塑造和创意实现及细节处理,教程比较简单,创意十足,看过<机械姬>电影的同学们一定知道这个有多炫 ...

  2. [SoapUI] 在SoapUI中通过Groovy脚本执行window命令杀掉进程

    //杀Excel进程 String line def p = "taskkill /F /IM EXCEL.exe".execute() def bri = new Buffere ...

  3. Python之路(第十八篇)shutil 模块、zipfile模块、configparser模块

    一.shutil 模块 1.shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中,需要打开文件 import shutil shutil.co ...

  4. c#使用Stopwatch来计算时间间隔

    今天要记录一个接口的耗时情况,就要求去写一段测试各个代码运行时间的方法,于是就加了这么一段代码.原来的做法是在代码执行之前和之后获取系统时间,然后相减.被改成了使用c#里的Stopwatch来计算时间 ...

  5. SpringBoot获取resource下证书失败

    1.第一种失败的情况:    本来使用Spring的上下文容器获取文件,将证书文件放在resource下,编译后获取文件会出现报错 java.security.spec.InvalidKeySpecE ...

  6. 实现WireCard支付

    实现WireCard支付,暂未完成 WireCardController.cs using System; using System.Collections.Generic; using System ...

  7. windows 10 开发学习资料,Windows-universal-samples学习笔记系列一:App settings

    windows 10 通用代码范例: https://github.com/Microsoft/Windows-universal-samples 相关视频:https://mix.office.co ...

  8. 装箱问题(NOIP2001&水题测试2017082401)

    题目链接:装箱问题 这题经典的01背包. 动规. 设计状态f[n][V]表示前n个物体放在V中的最大体积是多少. 所以代码如下: #include<bits/stdc++.h> using ...

  9. JNI,RegisterNative参数解析

    Register native method - 数据类型和method descriptor 使用JNI时,为了使得虚拟机可以找到在C/C++ code中定义的native方法,有两种机制可以用,一 ...

  10. linux中命令突然不能用

    先用:echo $PATH 发现path丢失:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 于是用临时环境变量 export ...