图解ThreadLocal原理

在项目中不少地方会用到ThreadLocal对象,用来实现线程之间资源隔离。现在通过图的方式接解刨其原理。

public static void main(String[] arg) throws InterruptedException, IOException {
        final ThreadLocal t = new ThreadLocal();
        Thread thread_1 = new Thread(new Runnable(){
            @Override
            public void run() {
                t.set("thread_1");
                try {
                    Thread.sleep(50);
                    System.out.println("thread_1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(t.get());
            }
        });
        Thread thread_2 = new Thread(new Runnable(){
            @Override
            public void run() {
                t.set("thread_2");
                try {
                    Thread.sleep(50);
                    System.out.println("thread_2");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(t.get());
            }
        });
        Thread thread_3 = new Thread(new Runnable(){
            @Override
            public void run() {
                t.set("thread_3");
                try {
                    Thread.sleep(50);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(t.get());
            }
        });
        thread_1.start();
        thread_2.start();
        thread_3.start();
        System.in.read();
        Thread.currentThread().join();

整个过程的关键就是:
1、每个线程都有自己的ThreadLocalMap对象;(ThreadLocal 多线程下资源隔离的根本原因)

2、各个线程在调用同一个ThreadLocal对象的set(value)设置值的时候,是往各自的ThreadLocalMap对象数组中设置值

3、至于当前值放置在数组中的下标位置,则是通过ThreadLocal对象的threadLocalHashCode计算而来。即多线程环境下ThreadLocal对象的threadLocalHashCode是共享的。

4、而ThreadLocal对象的threadLocalHashCode是一个原子自增的变量,通过类方法初始化值。
也即,ThreadLocal a = new ThreadLocal();就会初始化threadLocalHashCode值,这个值不会再变。所以,同一个线程在同一个ThreadLocal对象中set()值,只能保存最后一次set的值。

5、为什么每个线程都有自己的ThreadLocalMap对象,且是一个数组呢?
答:根据以上的分析,多个线程操作一个ThreadLocal对象就能达到线程之间资源隔离。而采用数组是因为可能一个线程需要通过多个ThreadLocal对象达到多个资源隔离。每个不同的ThreadLocal对象的threadLocalHashCode都不一样,也就映射到ThreadLocalMap对象数组下的不同下标。

6、每个线程的ThreadLocalMap对象是通过偏移位置的方式解决hash碰撞

7、每个线程都有自己的ThreadLocalMap对象也有扩容机制,且是天然线程安全的
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值