谈ThreadLocal中InheritableThreadLocal的用法以及ThreadLocalUtil类

例子1:

public class TestThreadLocal {
    
    public static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) {
        threadLocal.set(new Integer(123));
        
        Thread thread = new MyThread();
        thread.start();

        System.out.println("main = " + threadLocal.get());
    }
    
    static class MyThread extends Thread {
        
        @Override
        public void run() {
            System.out.println("MyThread = " + threadLocal.get());
        }
    }
}

输出:

main = 123

MyThread = null

例子2:

改用:InheritableThreadLocal()

public class TestThreadLocal2 {
    
    public static ThreadLocal<Integer> threadLocal = new InheritableThreadLocal<>();

    public static void main(String[] args) {
        threadLocal.set(new Integer(123));
        
        Thread thread = new MyThread();
        thread.start();

        System.out.println("main = " + threadLocal.get());
    }
    
    static class MyThread extends Thread {
        
        @Override
        public void run() {
            System.out.println("MyThread = " + threadLocal.get());
        }
    }
}

输出:

main = 123

MyThread = 123

例子3:

public class TestThreadLocal3 {
    
    public static ThreadLocal<Integer> threadLocal = new InheritableThreadLocal<>();

    public static void main(String[] args) {
        Thread thread2 = new MyThread2();
        thread2.start();
        
        Thread thread = new MyThread();
        thread.start();

        System.out.println("main = " + threadLocal.get());

    }
    
    static class MyThread extends Thread {
        
        @Override
        public void run() {
            System.out.println("MyThread = " + threadLocal.get());
        }
    }

    static class MyThread2 extends Thread {

        @Override
        public void run() {
            threadLocal.set(new Integer(123));
        }
    }
}

输出:

main = null

MyThread = null

分析:

例子1中:可以知道如果通过public static ThreadLocal threadLocal = new ThreadLocal<>();则父线程的threadLocal变量不能被子线程说获取。

例子2中:通过InheritableThreadLocal()可以实现子线程获取父线程的变量值。(该方法可以用在异步操作时,异步线程获取主线程的logId,这样就能将logId贯穿全文,但是项目中用到的是线程池,因此,改意义不是很大)

例子3中:通过InheritableThreadLocal()两个子线程间没有关系,则及时用了InheritableThreadLocal()也不能获取对方的变量。

 

这里给出一个本地线程工具类ThreadLocalUtil

/**
 * 本地线程工具类
 */
@Slf4j
public abstract class ThreadLocalUtil {
    
    private static final ThreadLocal<Map<Object, Object>> RESOURCES = new ThreadLocal<>();
    
    public static Map<Object, Object> getResources() {
        return RESOURCES != null ? new HashMap<Object, Object>(RESOURCES.get()) : null;
    }
    
    public static void setResources(Map<Object, Object> newResources) {
        if (CollectionUtils.isEmpty(newResources)) {
            return;
        }
        RESOURCES.get().clear();
        RESOURCES.get().putAll(newResources);
    }
    
    private static Object getValue(Object key) {
        return RESOURCES.get().get(key);
    }
    
    public static Object get(Object key) {
        Object value = getValue(key);
        log.info("Retrieved value of type [{}] for key [{}] bound to thread [{}].", value.getClass().getName(), key, Thread.currentThread().getName());
        return value;
    }
    
    public static Object remove(Object key) {
        Object value = RESOURCES.get().remove(key);
        
        log.info("Removed value of type [{}] for key [{}] from thread [{}].", value.getClass().getName(), key, Thread.currentThread().getName() );
        return value;
    }
    
    public static void put(Object key, Object value) {
        Preconditions.checkNotNull(key, "key cannot be null");
        if (null == value) {
            remove(key);
            return;
        }
        
        RESOURCES.get().put(key, value);
        log.info("Bound value of type [{}] for key [{}] to thread [{}].", value.getClass().getName(), key, Thread.currentThread().getName() );
    }
    
    public static void remove() {
        RESOURCES.remove();
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值