前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >给当前Thread类对象初始化ThreadlocalMap属性

给当前Thread类对象初始化ThreadlocalMap属性

原创
作者头像
好派笔记
修改2021-10-08 14:52:37
5450
修改2021-10-08 14:52:37
举报
文章被收录于专栏:好派笔记好派笔记

给当前Thread类对象初始化ThreadlocalMap属性:

代码语言:javascript
复制
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

到这里,我们就可以理解ThreadLocal究竟是如何工作的了

  1. Thread类中有一个成员变量属于ThreadLocalMap类(一个定义在ThreadLocal类中的内部类),它是一个Map,他的key是ThreadLocal实例对象。
  2. 当为ThreadLocal类的对象set值时,首先获得当前线程的ThreadLocalMap类属性,然后以ThreadLocal类的对象为key,设定value。get值时则类似。
  3. ThreadLocal变量的活动范围为某线程,是该线程“专有的,独自霸占”的,对该变量的所有操作均由该线程完成!也就是说,ThreadLocal 不是用来解决共享对象的多线程访问的竞争问题的,因为ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。当线程终止后,这些值会作为垃圾回收。
  4. 由ThreadLocal的工作原理决定了:每个线程独自拥有一个变量,并非是共享的,下面给出一个例子:
代码语言:javascript
复制
public class Son implements Cloneable{
    public static void main(String[] args){
        Son p=new Son();
        System.out.println(p);
        Thread t = new Thread(new Runnable(){  
            public void run(){
            	ThreadLocal<Son> threadLocal = new ThreadLocal<>();
            	System.out.println(threadLocal);
            	threadLocal.set(p);
            	System.out.println(threadLocal.get());
            	threadLocal.remove();
            	try {
					threadLocal.set((Son) p.clone());
					System.out.println(threadLocal.get());
				} catch (CloneNotSupportedException e) {
					e.printStackTrace();
				}
            	System.out.println(threadLocal);
            }}); 
        t.start();
    }
}

输出:

代码语言:javascript
复制
Son@7852e922
java.lang.ThreadLocal@3ffc8195
Son@7852e922
Son@313b781a
java.lang.ThreadLocal@3ffc8195

也就是如果把一个共享的对象直接保存到ThreadLocal中,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发访问问题。 所以要在保存到ThreadLocal之前,通过克隆或者new来创建新的对象,然后再进行保存。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档