Java ThreadLocal有什么作用你知道吗

目录
  • ThreadLocal有什么作用
    • 测试代码
      • 当前线程只能操作当前ThreadLocal定义的局部变量,其他线程是访问不了。
    • 测试结果
  • 总结

ThreadLocal有什么作用

ThreadLocal 的源码,可以看到源码注释中有很清楚的解释:它是线程的局部变量,这些变量只能在这个线程内被读写,在其他线程内是无法访问的。 ThreadLocal 定义的通常是与线程关联的私有静态字段(例如,用户ID或事务ID)。

ThreadLocal 是线程本地存储,在每个线程中都创建了一个 ThreadLocalMap 对象,每个线程可以访问自己内部 ThreadLocalMap 对象内的 value。通过这种方式,避免资源在多线程间共享。

经典的使用场景是为每个线程分配一个 JDBC 连接 Connection。这样就可以保证每个线程的都在各自的 Connection 上进行数据库的操作,不会出现 A 线程关了 B线程正在使用的 Connection; 还有 Session 管理 等问题。

比如用来存储用户 Session。Session 的特性很适合 ThreadLocal ,因为 Session 之前当前会话周期内有效,会话结束便销毁。我们先笼统但不正确的分析一次 web 请求的过程:

用户在浏览器中访问 web 页面;
浏览器向服务器发起请求;
服务器上的服务处理程序(例如tomcat)接收请求,并开启一个线程处理请求,期间会使用到 Session ;
最后服务器将请求结果返回给客户端浏览器。

从这个简单的访问过程我们看到正好这个 Session 是在处理一个用户会话过程中产生并使用的,如果单纯的理解一个用户的一次会话对应服务端一个独立的处理线程,那用 ThreadLocal 在存储 Session ,简直是再合适不过了。

测试代码

ThreadLocal 的使用非常简单,最核心的操作就是三个:创建、赋值、取值。

当前线程只能操作当前ThreadLocal定义的局部变量,其他线程是访问不了。

public class TestThreadLocal {
    //线程本地存储变量
    private static final ThreadLocal<Integer> THREAD_LOCAL_NUM = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };
    public static void main(String[] args) {
        for (int i = 0; i <3; i++) {//启动三个线程
            Thread t = new Thread() {
                @Override
                public void run() {
                    add10ByThreadLocal();
                }
            };
            t.start();
        }
    }
    /**
     * 线程本地存储变量加 5
     */
    private static void add10ByThreadLocal() {
        for (int i = 0; i <5; i++) {
            Integer n = THREAD_LOCAL_NUM.get();
            n += 1;
            THREAD_LOCAL_NUM.set(n);
            System.out.println(Thread.currentThread().getName() + " : ThreadLocal num=" + n);
        }
    }
}

测试结果

答案:三个线程最终输出是5,代表一个线程 执行代码循环五次每次+1结果是5 在同一个线程内, 三个线程最终结果 并不是15,从而得出结论ThreadLocal接线程的局部变量。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 面试官:java ThreadLocal真的会造成内存泄露吗

    目录 1.ThreadLocal知识体系 2.为什么会被设计为弱引用呢? 3.大量Entry造成的内存溢出问题探讨 总结 1.ThreadLocal知识体系 本文还是不能免俗,在回答这个问题之前需要先和大家介绍一下ThreadLocal的知识,使大家对ThreadLocal有一个相对全面的认识. ThreadLocal本地线程变量,主要用于解决数据访问的竞争,通常用于多租户.全链路压测.链路跟踪中保存线程上下文环境,在一个请求流转中非常方便的获取一些关键信息,例如当前的租户信息.压测标记. Th

  • ThreadLocal的基本原理

    目录 基本流程 ThreadLoalMap数据结构 Hash冲突及解决 ThreadLocal内存泄露 内存引用链路 引用类型 为什么使用弱引用而不是强引用? 泄露原因分析 ThreadLocal应用场景 源码实现 一个线程内可以存多个ThreadLocal对象,存储的位置位于Thread的ThreadLocal.ThreadLocalMap变量,在Thread中有如下变量: /* ThreadLocal values pertaining to this thread. This map is

  • Java中的ThreadLocal功能演示示例

    除了使用synchronized同步符号外,Java中的ThreadLocal是另一种实现线程安全的方法.在进行性能测试用例的编写过程中,比较简单的办法就是直接使用synchronized关键字,修饰对象.方法以及类.但是使用synchronized同步,这可能会影响应用程序的可伸缩性以及运行效率.但是如果要在多个线程之间共享对象又要保障线程安全,则除了synchronized之外没有特别适合测试的方法. Java中的ThreadLocal是实现线程安全的另一种方法,它不满足同步要求,而是通过为

  • Java中的ThreadLocal详解

    目录 一.ThreadLocal简介 二.ThreadLocal简单使用 三.ThreadLocal的实现原理 1.set方法源码 2.get方法源码 3.remove方法的实现 四.ThreadLocal不支持继承性 五.InheritableThreadLocal类 六.从ThreadLocalMap看ThreadLocal使用不当的内存泄漏问题 1.基础概念 2.分析ThreadLocalMap内部实现 一.ThreadLocal简介 多线程访问同一个共享变量的时候容易出现并发问题,特别是

  • Java单线程ThreadLocal串值问题解决方案

    ThreadLocal ThreadLocal 适用于变量在线程间隔离,而在方法或类间共享的场景. 代码 @RestController public class ThreadLocalController { private static final ThreadLocal<String> currentUid = ThreadLocal.withInitial(() -> null); @GetMapping("bad") public Map doBad(@Re

  • java中ThreadLocalRandom的使用详解

    在java中我们通常会需要使用到java.util.Random来便利的生产随机数.但是Random是线程安全的,如果要在线程环境中的话就有可能产生性能瓶颈. 我们以Random中常用的nextInt方法为例来具体看一下: public int nextInt() { return next(32); } nextInt方法实际上调用了下面的方法: protected int next(int bits) { long oldseed, nextseed; AtomicLong seed = t

  • Java中ThreadLocal的一些理解

    前言 面试的时候被问到ThreadLocal的相关知识,没有回答好(奶奶的,现在感觉问啥都能被问倒),所以我决定先解决这几次面试中都遇到的高频问题,把这几个硬骨头都能理解的透彻的说出来了,感觉最起码不能总是一轮游. ThreadLocal介绍 ThreadLocal是JDK1.2开始就提供的一个用来存储线程本地变量的类.ThreadLocal中的变量是在每个线程中独立存在的,当多个线程访问ThreadLocal中的变量的时候,其实都是访问的自己当前线程的内存中的变量,从而保证的变量的线程安全.

  • 详解Java中的ThreadLocal

    一.ThreadLocal简介 多线程访问同一个共享变量的时候容易出现并发问题,特别是多个线程对一个变量进行写入的时候,为了保证线程安全,一般使用者在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性.ThreadLocal是除了加锁这种同步方式之外的一种保证一种规避多线程访问出现线程不安全的方法,当我们在创建一个变量后,如果每个线程对其进行访问的时候访问的都是线程自己的变量这样就不会存在线程不安全问题. 二.ThreadLocal简单使用 下面的例子中,开启两个线程,在每个线程内部设置

  • java中ThreadLocal取不到值的两种原因

    1.两种原因 第一种,也是最常见的一种,就是多个线程使用ThreadLocal 第二种,类加载器不同造成取不到值,本质原因就是不同类加载器造成多个ThreadLocal对象 public class StaticClassLoaderTest { protected static final ThreadLocal<Object> local = new ThreadLocal<Object>(); //cusLoader加载器加载的对象 private Test3 test3;

  • Java ThreadLocal原理解析以及应用场景分析案例详解

    目录 ThreadLocal的定义 ThreadLocal的应用场景 ThreadLocal的demo TheadLocal的源码解析 ThreadLocal的set方法 ThreadLocal的get方法 ThreadLocalMap的结构 ThreadLocalMap的set方法 ThreadLocalMap的getEntry方法 ThreadLocal的内存泄露 如何避免内存泄露呢 应用实例 实际应用二 总结 ThreadLocal的定义 JDK对ThreadLocal的定义如下: The

  • JAVA开发常用类库UUID、Optional、ThreadLocal、TimerTask、Base64使用方法与实例详解

    1.UUID类库 UUID 根据时间戳实现自动无重复字符串定义 // 获取UUID public static UUID randomUUID() // 根据字符串获取UUID public static UUID fromString(String name) 应用:对文件进行自动命名处理 import java.util.UUID; class Demo { public static void main(String[] args) { System.out.println(UUID.ra

随机推荐