ThreadLocal的使用及剖析

本文讨论了如何在多线程环境中利用ThreadLocal避免频繁传递参数,以及其与工厂模式、单例的区别。重点讲解了ThreadLocal维护线程本地实例的优势和同步机制,以及其他潜在的实现方式如Map映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好久未用,来复习一下。

可供参考的文章

使用场景

  1. 多线程下,该变量在每个线程中都是不同的实例,该变量调用链很深,不想每一层的方法中都放一个形参。

比如一个demo:

	
object Test {

    var name: ThreadLocal<String> = ThreadLocal()

    fun work() {
        //synchronized(this) {
            PrintService.work()
        //}
    }
}


object PrintService {

    fun work() {
        (1..9).forEach {
            PrintDao.work(it)
        }
    }
}

object PrintDao {

    fun work(num: Int) = println("${Thread.currentThread()} name is ${Test.name.get()} print $num")
}

fun main() {
    (1..9).forEach {
        thread(name = "Thread$it") {
            Test.name.set(Thread.currentThread().name)
            Test.work()
            Test.name.remove()
        }
    }
    
}

这里大可以在每个方法上加一个形参name,依赖注入,thread里实例化这个形参也可以。
那如果我们的调用链很深,如果在每个方法上都加这么一个参数,而使用的地方在最低部,那这种方式是不是不优美,上游给下游传了个参数,结果只是为了参数往更下游传递。

那我们如果也类似的把这个参数放在一个工厂或单例里,不用ThreadLocal的话可以吗?当然可以,我们甚至可以创建一个Map<Thread,Object>的映射,来完成线程间不同的实例获取,那ThreadLocal实际上就帮我们做了这个事情,且做的更好了。

Thread维护ThreadLocal -> 实例,采用ThreadLocalMap完成这个映射关系。

如果直接用ThreadLocal完成Thread -> 实例的映射,那么每次增删线程都需要对映射map进行修改,涉及多线程并发的修改就得加锁,而这个映射关系如果放到线程内部就不再需要加锁了,因为单个线程只维护自己的ThreadLocal ->实例的映射,自然不会与其他线程产生交集。

未完,有空再写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值