ThreadLocal的作用:用来存当前线程的局部变量,不同线程间互不干扰。拿完数据记得需要移除数据,不然JVM不会将ThreadLocal回收(可能还会被引用),多了就会出现内存泄漏的情况。

springboot中如何使用ThreadLocal?

其实很简单,就是将ThreadLocal变成一个bean(也就是初始化ThreadLocal<T>),在不同层间用同一个对象就行。

写一个小demo。

1.初始化ThreadLocal

package com.yblue.config;

import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author JiaXinMa
 * @description 使用ThreadLocal
 * @date 2021/7/12
 */
@Component
public class ThreadLocalConfig {

    // jdk建议将 ThreadLocal 定义为 private static ,这样就不会有弱引用,内存泄漏的问题了
    private final static ThreadLocal<Map> mapThreadLocal = new ThreadLocal<>();
    
    
    //获取当前线程的存的变量
    public Map get() {
        return mapThreadLocal.get();
    }

    //设置当前线程的存的变量
    public void set(Map map) {
        this.mapThreadLocal.set(map);
    }

    //移除当前线程的存的变量
    public void remove() {
        this.mapThreadLocal.remove();
    }
    
}

2.控制层

package com.yblue.controller;

import com.yblue.config.ThreadLocalConfig;
import com.yblue.service.ThreadLocalTestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author JiaXinMa
 * @description 测试ThreadLocal
 * @date 2021/7/12
 */
@RestController
public class ThreadLocalTestController {

    @Autowired
    ThreadLocalTestService threadLocalTestService;

    @Autowired
    ThreadLocalConfig threadLocalConfig;

    @GetMapping("/threadLocal")
    public void test(String userId) {

        Map map = new HashMap<String, String>();
        map.put("userId", userId);

        threadLocalConfig.set(map);

        threadLocalTestService.threadLocalTest();
    }

}

3.业务层

package com.yblue.service;

import com.yblue.config.ThreadLocalConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @author JiaXinMa
 * @description 测试ThreadLocal
 * @date 2021/7/12
 */
@Service
public class ThreadLocalTestService {

    @Autowired
    ThreadLocalConfig threadLocalConfig;

    public void threadLocalTest() {

        Map map = threadLocalConfig.get();

        System.out.println("当前线程:" + Thread.currentThread().getName() + "的用户id:" + map.get("userId"));
        
        threadLocalConfig.remove();
    }
}

 

效果如下:

springboot中如何使用ThreadLocal?_java