TreadLocal用法和实现原理

import java.util.HashMap;

public class TreadLocalTest {

    static ThreadLocal<HashMap> map0 = new ThreadLocal<HashMap>(){ 
        @Override 
        protected HashMap initialValue() { 
            System.out.println(Thread.currentThread().getName()+"initialValue"); 
            return new HashMap(); 
        } 
    }; 
    public void run(){ 
        Thread[] runs = new Thread[3]; 
        for(int i=0;i<runs.length;i++){ 
            runs[i]=new Thread(new T1(i)); 
        } 
        for(int i=0;i<runs.length;i++){ 
            runs[i].start(); 
        } 
    } 
    public static class T1 implements Runnable{ 
        int id; 
        public T1(int id0){ 
            id = id0; 
        } 
        public void run() { 
            System.out.println(Thread.currentThread().getName()+":start"); 
            HashMap map = map0.get(); 
            for(int i=0;i<10;i++){ 
                map.put(i, i+id*100); 
                try{ 
                    Thread.sleep(100); 
                }catch(Exception ex){ 
                } 
            } 
            System.out.println(Thread.currentThread().getName()+':'+map); 
        } 
    } 
    /** 
     * Main 
     * @param args 
     */ 
    public static void main(String[] args){ 
        TreadLocalTest test = new TreadLocalTest(); 
        test.run(); 
    }

}

输出解释;

Thread-1:start 
Thread-2:start 
Thread-0:start 
Thread-2initialValue 
Thread-1initialValue 
Thread-0initialValue 
Thread-1:{0=100, 1=101, 2=102, 3=103, 4=104, 5=105, 6=106, 7=107, 8=108, 9=109} 
Thread-2:{0=200, 1=201, 2=202, 3=203, 4=204, 5=205, 6=206, 7=207, 8=208, 9=209} 
Thread-0:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}

可以看到map0 虽然是个静态变量,但是initialValue被调用了三次,通过debug发现,initialValue是从map0.get处发起的。而且每个线程都有自己的map,虽然他们同时执行。

进入Theadlocal代码,可以发现如下的片段;

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

这说明ThreadLocal确实只有一个变量,但是它内部包含一个map,针对每个thread保留一个entry,如果对应的thread不存在则会调用initialValue。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadLocal是一个Thread的局部变量,它可以在每个线程中存储和获取值。它并不是一个Thread,而是Thread的局部变量。可以将ThreadLocal理解为一个容器,每个线程都有自己独立的容器,用于存储和获取值。\[1\]\[2\]\[3\]通过ThreadLocal,我们可以实现线程间的变量隔离,即不同线程对同一个ThreadLocal对象存储的值是独立的,而在同一个线程中,对ThreadLocal对象存储的值的访问是共享的。\[3\]ThreadLocal的底层实现是通过ThreadLocalMap来存储和获取值,每个线程都有自己的ThreadLocalMap对象。\[2\]可以通过ThreadLocal的set方法设置值,通过get方法获取值,通过remove方法移除值。\[4\] #### 引用[.reference_title] - *1* *3* [ThreadLocal详解](https://blog.csdn.net/zhiyikeji/article/details/125473692)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [ThreadLocal是什么?](https://blog.csdn.net/m0_56190554/article/details/128028532)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值