ThreadLocal理解

  1. 使用ThreadLocal的时候我们保证了每个线程可以隔离使用对象,避免线程间的数据干扰。

常用例子

1public class ThreadLocalTest { 2 3 public static void main(String[] args) throws InterruptedException { 4 ThreadLocal tl=new ThreadLocal(); 5 tl.set("123"); 6 System.out.println(Thread.currentThread()+":"+tl.get()); 7 8 Thread t=new Thread( 9 new Runnable() { 10 public void run() { 11 tl.set("456"); 12 System.out.println(Thread.currentThread()+":"+tl.get()); 13 } 14 }); 15 t.start(); 16 Thread.sleep(1000); 17 System.out.println(Thread.currentThread()+":"+tl.get()); 18}} 19 20结果: 21 22Thread[main,5,main]:123 23Thread[Thread-0,5,main]:456 24Thread[main,5,main]:123 25

从上面的例子可以看出来,每个线程保存的对象是隔离的!

  1. 代码分析

    下面是Thread里面定义的对象,它的声明是在ThreadLocal里面的一个静态子类对象 ThreadLocal.ThreadLocalMap threadLocals = null;

    这里是ThreadLocal的对象定义 static class ThreadLocalMap { static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; //可以看出key为当前的ThreadLocal对象,value为保存的数据对象 Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } }

下面set/get/getMap/createMap方法,可以存储数据

1public void set(T value) { 2 //获取当前线程 3 Thread t = Thread.currentThread(); 4 //根据当前的线程获取数据 5 ThreadLocalMap map = getMap(t); 6 if (map != null) 7 map.set(this, value); 8 else 9 createMap(t, value); 10 } 11 12public T get() { 13 //获取当前线程 14 Thread t = Thread.currentThread(); 15 //根据当前的线程获取数据 16 ThreadLocalMap map = getMap(t); 17 if (map != null) { 18 //这里依据对象获取保存的数据 19 ThreadLocalMap.Entry e = map.getEntry(this); 20 if (e != null) { 21 @SuppressWarnings("unchecked") 22 T result = (T)e.value; 23 return result; 24 } 25 } 26 return setInitialValue(); 27 } 28 29 /** 30 * 这里可以看出返回的数据是当前的线程变量 31 */ 32 ThreadLocalMap getMap(Thread t) { 33 return t.threadLocals; 34 } 35 36 void createMap(Thread t, T firstValue) { 37 t.threadLocals = new ThreadLocalMap(this, firstValue); 38} 39 40 41从上面可以看出写的代码示例,返回值是不同的因为线程是独立的, 42独立线程会有自己的单独数据存储map, 43至于ThreadLocal当作key是为了防止多个ThreadLocal在同一个线程当中做区分

3. ThreadLocal做保存数据的key唯一性

1//ThreadLocal类中有一个被final修饰的类型为int的threadLocalHashCode,它在该ThreadLocal被构造的时候就会生成,相当于一个ThreadLocal的ID 2 private final int threadLocalHashCode = nextHashCode(); 3 //threadLocalHashCode值来源于这里 4 private static AtomicInteger nextHashCode =new AtomicInteger(); 5 private static final int HASH_INCREMENT = 0x61c88647; 6 private static int nextHashCode() { 7 return nextHashCode.getAndAdd(HASH_INCREMENT); 8 }
点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

ThreadLocal源码解析及实战应用

ThreadLocal是一个关于创建线程局部变量的类。通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。ThreadLocal在设计之初就是为解决并发问题而提供一种方案,每个线程维护一份自己的数据,达到线程隔离的效果。

ThreadLocal源码分析

最近在学多线程并发的知识,发现好像ThreadLoca还挺重要,决定看看源码以及查找各方资料来学习一下。ThreadLocal能够提供线程的局部变量,让每个线程都可以通过set/get来对这个局部变量进行操作,不会和其它线程的局部变量进行冲突,实现了线程的数据隔离。首先是ThreadLocal的结构:每个Thread维护一个ThreadLocalMap,这个

Java多线程与并发之ThreadLocal原理解析

1\.ThreadLocal是什么?使用场景ThreadLocal简介ThreadLocal是线程本地变量,可以为多线程的并发问题提供一种解决方式,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,

JAVA ThreadLocal对象浅析

最近在开发过程中,在做一个字典项服务的时候,最开始采用了ThreadLocal对象来缓存数据。在使用ThreadLocal过程中遇到一些问题,这里和大家分享一下。一、什么是ThreadLocal?顾名思义它是localvariable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值

Java并发编程的艺术笔记(四)——ThreadLocal的使用

ThreadLocal,即线程变量,是一个以ThreadLocal对象为键、任意对象为值的存储结构。这个结构被附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值。目的就是为了让线程能够有自己的变量可以通过set(T)方法来设置一个值,在当前线程下再通过get()方法获取到原先设置的值