ThreadLocal类学习笔记

本文深入解析了Java中的ThreadLocal机制,介绍了其基本概念、应用场景及内部实现原理,并通过示例展示了如何利用ThreadLocal来简化多线程编程。

这个类在java1.2中就出现了,线程独有的变量(每个线程都有一份变量),使用它的好处之一就是可以少传许多参数。

在哪里用到它呢?有连接池的地方就有它的身影,连接池包括数据库连接池,网络连接池等。

import java.util.UUID;

class Factory {
    static ThreadLocal<String> connection=new ThreadLocal<>();
    static String getConnection() {
        String s=connection.get();
        if (s == null) {
            connection.set(UUID.randomUUID().toString());
        }
        return connection.get();
    }
}
public class TestThreadLocal {
    static void f() {
        String s = Factory.getConnection();
        System.out.println("f :" + s);
        g();
    }
    static void g() {
        String s = Factory.getConnection();
        System.out.println("g :" + s);
    }
    public static void main(String[] args) {
        new Thread(() -> f()).start();
        new Thread(() -> f()).start();
    }
}

输出结果:

f :6c71fba2-8fd6-4de9-88f9-69023290e213
f :c315c241-b379-446d-8159-dc758f020a80
g :c315c241-b379-446d-8159-dc758f020a80
g :6c71fba2-8fd6-4de9-88f9-69023290e213

ThreadLocal<String>connection这个变量其实就是一个马甲,它是唯一的一份(因为它是静态的呀)。这唯一的一份就相当于一个线程大管家,它负责去访问当前线程。请看ThreadLocal#get方法

public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

第一步,它会去获取当前线程t

第二步,通过当前线程t获取ThreadLocalMap对象map

第三步,如果没有map,那就给当前线程new出来一个并赋上初值(通过setInitialValue来实现);如果已经存在,那就读取之。

ThreadLocalMap这个类是一个内部静态类,全名是:ThreadLocal.ThreadLocalMap,其内部元素的键就是this(也就是ThreadLocal实例,即上例中的connection变量),值是Object类型的实例。

    Entry(ThreadLocal<?> k, Object v)

Thread这个类大名鼎鼎,它内部有一个成员变量:

    ThreadLocal.ThreadLocalMap threadLocals = null;

上例中,线程1和线程2各有一份ThreadLocalMap成员变量threadLocals,这两个threadLocals中都有同一份键:connection,但是它们的值不是同一份。

每一个线程都维持一份ThreadLocalMap threadLocals,ThreadLocal这个大管家负责访问当前线程对象的threadLocals变量

可见,ThreadLocal机制是纯java代码,没有底层实现,我们自己也是可以实现的,这是一种巧妙地机制。

ThreadLocal和ThreadLocalMap在同一个文件里面并且ThreadLocalMap是ThreadLocal的静态内部类,然后Thread又有ThreadLocalMap的成员变量,最后ThreadLocal变量作为一个大管家去访问ThreadLocalMap。这个API设计的真是合理,就该这么整啊!实现起来简简单单,却带来许多便利。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值