ThreadLocal ThreadContext 存储多个线程变量,跨类获取

(线程上线文)

一、自定义类使用ThreadLocal

可以创建多个ThreadLocal变量

ThreadLocal<HashMap>存储多个变量,感觉用起来不是很方便。使用需要测试。

感觉没必要用ConcurrentHasMap,因为ThreadLocal本身就是线程变量。应该不会有线程冲突。

import java.util.HashMap;

public class ThreadContextHolder {

    //一个变量
    private static final ThreadLocal<String> redisId = new ThreadLocal<>();

    //另一个变量
    private static final ThreadLocal<String> remoteAddr = new ThreadLocal<>();

    //Map放多个变量
    protected static final ThreadLocal<HashMap> authMap = new ThreadLocal<HashMap>();

    public static String getRedisId() {
        return ThreadContextHolder.redisId.get();
    }

    public static void setRedisId(String redisId) {
        ThreadContextHolder.redisId.set(redisId);
    }

    public static String getRemoteAddr() {
        return ThreadContextHolder.remoteAddr.get();
    }

    public static void setRemoteAddr(String remoteAddr) {
        ThreadContextHolder.remoteAddr.set(remoteAddr);
    }

    public static HashMap getAuthMap() {
        return ThreadContextHolder.authMap.get();
    }

    public static void setAuthMap(HashMap authMap) {
        ThreadContextHolder.authMap.set(authMap);
    }


    public static void main(String[] args) throws Exception {

        try{
            ThreadContextHolder.redisId.set("redisId1");
            ThreadContextHolder.remoteAddr.set("remoteAddr1");

            //其他类调用
            System.out.println(ThreadContextHolder.getRedisId());
            System.out.println(ThreadContextHolder.getRemoteAddr());
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            //清理,避免内存泄露
            ThreadContextHolder.remoteAddr.remove();
            ThreadContextHolder.redisId.remove();
        }

        try{
            HashMap map1 = new HashMap();
            map1.put("a1", "a1");
            map1.put("a2", "a2");
            authMap.set(map1);

            //其他类调用
            HashMap map2 = ThreadContextHolder.getAuthMap();
            System.out.println(map2.get("a1"));
            System.out.println(map2.get("a2"));
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            ThreadContextHolder.authMap.remove();
        }

        //线程调试
        new Thread(() -> {
            //...
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread-1").start();

    }
}

 二、JDK内部ThreadContext类

com.sun.jmx.snmp.ThreadContext,在JDK 9中移除,不推荐使用。

可以自己复制一份。感觉也没那么好用,主要是清理这块,有点特殊。

java 线程上下文是内部专有API,将来可能会删除 _大数据知识库

//ThreadContext oldContext = ThreadContext.push(stringKey, objectValue);
ThreadContext oldContext = null;
try {
    oldContext = ThreadContext.push("stringKey1","objectValue1");
    ThreadContext.push("stringKey2","objectValue2");
} finally {
    if (oldContext != null) {
        ThreadContext.restore(oldContext);
    }
}

//其他类调用
String value1 = ThreadContext.get("stringKey1");
Object value2 = ThreadContext.get("stringKey2");

三、log4j(和shiro)的ThreadContext类

log4j和shiro 带ThreadContext类,但是感觉用他们的(依赖他们的)不好,使用倒是方便

log4j

org.apache.logging.log4j.ThreadContext

try {
    ...
    ThreadContext.put("stringKey1", "stringvalue1");
    ThreadContext.put("stringKey2", "stringvalue2");
}
catch (Exception e){
    e.printStackTrace();
}
finally {
    //清除ThreadContext,避免内存泄露
    ThreadContext.clearAll();
}

//其他类调用
String value1 = ThreadContext.get("stringKey1");
String value2 = ThreadContext.get("stringKey2");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值