Java并发编程ThreadLocal

 借鉴:百度安全验证

前言:

当多线程访问共享可变数据时,涉及到线程间同步的问题,并不是所有时候,都要用到共享数据,所以就需要线程封闭出场了。

数据都被封闭在各自的线程之中,就不需要同步,这种通过将数据封闭在线程中而避免使用同步的技术称为线程封闭。

本文主要介绍线程封闭中的其中一种体现:ThreadLocal,将会介绍什么是 ThreadLocal;从 ThreadLocal 源码角度分析,最后介绍 ThreadLocal 的应用场景。

什么是 ThreadLocal?

ThreadLocal 是 Java 里一种特殊变量,它是一个线程级别变量,每个线程都有一个 ThreadLocal 就是每个线程都拥有了自己独立的一个变量,竞态条件被彻底消除了,在并发模式下是绝对安全的变量。

可以通过 ThreadLocal<T> value = new ThreadLocal<T>() 来使用。

会自动在每一个线程上创建一个 T 的副本,副本之间彼此独立,互不影响,可以用 ThreadLocal 存储一些参数,以便在线程中多个方法中使用,用以代替方法传参的做法。

下面通过例子来了解下 ThreadLocal:

public class ThreadLocalDemo {
    public static final ThreadLocal<String> THREAD_LOCAL = new ThreadLocal<>();

    public static void main(String[] args) throws InterruptedException {
        new ThreadLocalDemo().threadTest();
    }

    private void threadTest() throws InterruptedException {
        THREAD_LOCAL.set("main");
        String resultStart = THREAD_LOCAL.get();
        System.out.println("Thread-0执行之前:" + 
                Thread.currentThread().getName() + " threadLocal:" + resultStart);
        new Thread(new Runnable() {
            @Override
            public void run() {
                String resultIng1 = THREAD_LOCAL.get();
                System.out.println(Thread.currentThread().getName() + " threadLocal:" + resultIng1);
                THREAD_LOCAL.set("test02");
                String resultIng2 = THREAD_LOCAL.get();
                System.out.println("Thread-0重新设置之后:" + 
                        Thread.currentThread().getName() + " threadLocal:" + resultIng2);
            }
        }

        ).start();

        Thread.sleep(3000);
        String resultEnd = THREAD_LOCAL.get();
        System.out.println("Thread-0执行之后:" + 
                Thread.currentThread().getName() + " threadLocal:" + resultEnd);
    }
}

结果

Thread-0执行之前:main threadLocal:main
Thread-0 threadLocal:null
Thread-0重新设置之后:Thread-0 threadLocal:test02
Thread-0执行之后:main threadLocal:main

 结论:

这个变量在不同线程中取到的值是不同的,不同线程之间对于 ThreadLocal 会有对应的副本,这就是线程的封闭

使用场景:

用户登录的时候将用户信息保存到缓存中,每次解析token,然后一层一层的传递?这样会不会导致代码太过耦合呢?使用ThreadLocal在登录拦截器中在当前线程中保存用户信息,这样就可以直接从全局的ThreadLocal中很方便的获取用户信息。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值