这次的博客带来的是关于ThreadLocal<T>的理解
什么是ThreadLocal呢?根据名称来看,ThreadLocal即线程本地的意思。另外它还是一个范型类,这个范型T,就是threadLocal.set(T)的参数,也是threadLocal.get()、threadLocal.initialValue()的返回值。
public class ThreadLocal<T> { omitted ...... }
那么ThreadLocal又是如何区分不同线程的呢?
在ThreadLocal类内,还有一个静态内部类ThreadLocalMap
// ThreadLocalMap is a customized hash map suitable only for // maintaining thread local values. static class ThreadLocalMap { static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } omitted ...... }
这个内部类,是一个自定义的hashmap,内部Entry的构造函数需要一个ThreadLocal,以及与这个ThreadLocal关联的对象。
但是我们又会发现,ThreadLocalMap类的实例却没有在ThreadLocal中声明,而是在Thread类中
public class Thread implements Runnable { /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null; omitted ...... }
每个Thread维护一个ThreadLocalMap映射表,这个映射表的key是ThreadLocal实例本身,value是真正需要存储的Object。
所以知道了,在ThreadLocal中并没有进行copy操作,不像以前理解的拷贝副本那样,下面举一个例子:
public class ThreadLocalTest { private static People people = new People(); private static ThreadLocal<People> threadLocal = new ThreadLocal<People>(){ public People initialValue(){ return people; } }; public static void main(String[] args) throws InterruptedException { new Thread(new Runnable() { @Override public void run() { threadLocal.get().age = 5; System.out.println("people = " + threadLocal.get() + "age = " + threadLocal.get().age); } }).start(); Thread.sleep(10); new Thread(new Runnable() { @Override public void run() { System.out.println("people = " + threadLocal.get() + "age = " + threadLocal.get().age); } }).start(); } } class People { public int age; }
这样一来,在任何一个thread中修改people对象的age,都能够在另外的一个线程中看到
打印结果:
people = thread.People@6f5ab880age = 5
people = thread.People@6f5ab880age = 5
如果将threadLocal中的initialValue()的返回值改为new People,那么才不会相互影响
private static ThreadLocal<People> threadLocal = new ThreadLocal<People>(){ public People initialValue(){ return new People(); } };
打印结果为:
people = thread.People@44bacfa2age = 5
people = thread.People@44bacfa2age = 0
当然,文章还有很多没有讲,比如如何set,不过不想继续贴源码了,到此为止
相关推荐
java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多...
理解ThreadLocal 理解ThreadLocal 理解ThreadLocal 理解ThreadLocal
通常复杂的处理流程中,我们会使用一些异步处理的手段,那么这种场景下ThreadLocal即可能出现获取失败的问题。 public class ThreadLocalTest { public static void main(String[] args) { ThreadLocal ...
ThreadLocal应用示例及理解,这个写了相关的示例,可以参考一下。
应用ThreadLocal进行多线程处理,经典小例子。可运行。
早在 JDK 1.2 的时代,java.lang.ThreadLocal 就诞生了,它是为了解决多线程并发问题而设计的,只不过设计得有些难用,所以至今没有得到广泛使用。其实它还是挺有用的,不相信的话,我们一起来看看这个例子吧。 一个...
目录一、背景介绍二、TestNG多线程详解2.1 TestNG多线程实现2.2 TestNG多线程效果演示三、ThreadLocal3.1 ThreadLocal概念3.2 具体实现 一、背景介绍 在使用Selenium+TestNG做WebUI自动化过程中,为了能够加快Web...
正确理解ThreadLocal.pdf
Java中ThreadLocal工具类(解决多线程程序中并发问题的一种新思路,主要为参数的拷贝问题),感兴趣的话可以查看博文,博文地址:http://blog.csdn.net/otengyue/article/details/38459327
本例以序列号生成的程序为例,展示ThreadLocal的使用
ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量
java核心知识点学习----多线程间的数据共享和对象独立,ThreadLocal详解.pdf
首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象。
主要介绍了java 中ThreadLocal本地线程和同步机制的比较的相关资料,需要的朋友可以参考下
目录SimpleDateFormat诡异bug复现SimpleDateFormat诡异bug字符串日期转Date日期(parse)Date日期转String类型(format)SimpleDateFormat出现bug的原因如何解决SimpleDateFormat多线程安全问题局部变量使用...
ThreadLocal原理及在多层架构中的应用
synchronized关键字不属于方法特征签名的一...注意:使用synchronized是对哪个对象加的锁。 如果在一个类内部都是使用synchronized关键字定义了方法f(),g()。那么当使用这个类的实例调用f()时,就不能再调用g()方法。
详解java底层实现原理,ThreadLocal底层实现的数据结构,为什么不会导致内存泄露