谈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();
    }
}

发布了164 篇原创文章 · 获赞 113 · 访问量 68万+

猜你喜欢

转载自blog.csdn.net/timchen525/article/details/81194411