Java中ThreadLocal的用法

ThreadLocal的作用是能存储一个跟随线程的变量,线程未结束前你可以设置以及获取值。

* This class provides thread-local variables.  These variables differ from
* their normal counterparts in that each thread that accesses one (via its
* {@code get} or {@code set} method) has its own, independently initialized
* copy of the variable. 

如下是一个使用ThreadLocal的示例,展示了ThreadLocal的用法。

ThreadLocal设置和获取当前线程的变量值,当线程消亡时,不能通过线程获取变量。

当线程存活时,可以先设置好ThreadLocal的值后,在线程的各个地方都可以拿到该值。

由于ThreadLocal使用的是WeakReference,可能出现垃圾回收,所以慎重使用。

ThreadA.java

package com.example.demo.concurrent.threadlocal;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Slf4j
public class ThreadA extends Thread {

    @Override
    public void run() {
        try {
            for (int i = 0; i < 10; i++) {
                 ThreadLocalTool.local.set("ThreadA"+(i+1));
                 log.info("ThreadA{}, get value:{}",i+1, ThreadLocalTool.local.get());
                TimeUnit.MICROSECONDS.sleep(200);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
package com.example.demo.concurrent.threadlocal;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

@Slf4j
public class ThreadB extends Thread {

    @Override
    public void run() {
        try {
            for (int i = 0; i < 10; i++) {
                 ThreadLocalTool.local.set("ThreadB"+(i+1));
                 log.info("ThreadB{}, get value:{}",i+1, ThreadLocalTool.local.get());
                TimeUnit.MICROSECONDS.sleep(200);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

ThreadLocalDemo.java

package com.example.demo.concurrent.threadlocal;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Slf4j
public class ThreadLocalDemo {
    public static ThreadLocalExt local = new ThreadLocalExt();

    public static void main(String[] args) {
        ThreadA threadA = new ThreadA();
        ThreadB threadB = new ThreadB();
        threadA.start();
        threadB.start();
        try {
            for (int i = 0; i < 10; i++) {
                if (i==0){
                    log.info("Thread_Main{}初始值为:{}",i+1, local.get());
                }
                ThreadLocalTool.local.set("Thread_Main"+(i+1));
                log.info("Thread_Main{}, get value:{}",i+1, ThreadLocalTool.local.get());
                TimeUnit.MICROSECONDS.sleep(200);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

执行结果是:

01:04:15.189 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA1, get value:ThreadA1
01:04:15.189 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main1初始值为:ThreadLocal default value.
01:04:15.189 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB1, get value:ThreadB1
01:04:15.199 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main1, get value:Thread_Main1
01:04:15.200 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA2, get value:ThreadA2
01:04:15.201 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB2, get value:ThreadB2
01:04:15.201 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main2, get value:Thread_Main2
01:04:15.202 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA3, get value:ThreadA3
01:04:15.203 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main3, get value:Thread_Main3
01:04:15.203 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB3, get value:ThreadB3
01:04:15.204 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main4, get value:Thread_Main4
01:04:15.204 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB4, get value:ThreadB4
01:04:15.204 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA4, get value:ThreadA4
01:04:15.206 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main5, get value:Thread_Main5
01:04:15.206 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB5, get value:ThreadB5
01:04:15.206 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA5, get value:ThreadA5
01:04:15.208 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA6, get value:ThreadA6
01:04:15.208 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB6, get value:ThreadB6
01:04:15.208 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main6, get value:Thread_Main6
01:04:15.210 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA7, get value:ThreadA7
01:04:15.210 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main7, get value:Thread_Main7
01:04:15.210 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB7, get value:ThreadB7
01:04:15.212 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main8, get value:Thread_Main8
01:04:15.212 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA8, get value:ThreadA8
01:04:15.212 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB8, get value:ThreadB8
01:04:15.214 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB9, get value:ThreadB9
01:04:15.216 [Thread-1] INFO com.example.demo.concurrent.threadlocal.ThreadB - ThreadB10, get value:ThreadB10
01:04:15.217 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA9, get value:ThreadA9
01:04:15.217 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main9, get value:Thread_Main9
01:04:15.219 [main] INFO com.example.demo.concurrent.threadlocal.ThreadLocalDemo - Thread_Main10, get value:Thread_Main10
01:04:15.219 [Thread-0] INFO com.example.demo.concurrent.threadlocal.ThreadA - ThreadA10, get value:ThreadA10

ThreadLocal的核心是ThreadLocal.ThreadLocalMap,ThreadLocalMap与HashMap类似,都是存储的key、value数据,key是当前线程,value就是set()方法的值。

public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

详细解析可以参考ThreadLocal源码解读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞翔的咩咩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值