2024.9.26 ThreadLocal

在使用 ThreadLocal 的情况下,并发量很高时不会产生冲突,原因如下:

1. 线程隔离

  • ThreadLocal 为每个线程提供独立的存储空间。每个线程都可以安全地设置和获取其自己的变量值,而不会影响其他线程。即使在高并发环境下,线程间的数据是隔离的。

2. 并发安全

  • ThreadLocal 本身是线程安全的。由于每个线程都有自己的副本,所以即使多个线程同时操作 ThreadLocal 变量,也不会造成数据竞争或冲突。

3. 线程池的使用

  • 在使用线程池时,线程会被复用。为了避免旧数据的泄漏,必须确保在请求处理结束时调用 remove() 方法清除 ThreadLocal 中的值。这能有效避免在不同请求之间共享数据。

注意事项

尽管 ThreadLocal 在并发环境中提供了安全性,但仍需关注以下几个方面:

  1. 内存泄漏

    • 如果不调用 remove() 清理 ThreadLocal 变量,线程在池中复用时可能会持有旧值,导致内存泄漏。
  2. 性能

    • 高并发情况下,ThreadLocal 的使用不会显著影响性能,但在设计上仍需确保它是合适的选择,避免不必要的复杂性。
  3. 资源管理

    • 确保 ThreadLocal 的生命周期与请求的生命周期一致,避免因错误的使用造成资源占用。
public class UserContext {
    private static final ThreadLocal<Long> tl = new ThreadLocal<>();

    /**
     * 保存当前登录用户信息到ThreadLocal
     * @param userId 用户id
     */
    public static void setUser(Long userId) {
        tl.set(userId);
    }

    /**
     * 获取当前登录用户信息
     * @return 用户id
     */
    public static Long getUser() {
        return tl.get();
    }

    /**
     * 移除当前登录用户信息
     */
    public static void removeUser(){
        tl.remove();
    }
}
-------
public class ThreadLocalUtil {
    //提供ThreadLocal对象,
    private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();

    //根据键获取值
    public static <T> T get() {
        return (T) THREAD_LOCAL.get();
    }

    //存储键值对
    public static void set(Object value) {
        THREAD_LOCAL.set(value);
    }


    //清除ThreadLocal 防止内存泄漏
    public static void remove() {
        THREAD_LOCAL.remove();
    }


}
posted @ 2024-09-26 20:26  258333  阅读(5)  评论(0编辑  收藏  举报