Java-ThreadLocal

简述

一种线程绑定机制,每个线程都拥有对象的独立副本,不会与其他线程冲突,从而避免了并发与同步问题。

结构

ThreadLocal结构.png

每个线程都有一个ThreadLocalMap,其中Key为ThreadLocal对象,Value为用户对象的值

****ThreadLocal只是作为Key标识,并不存放任何数据,真正存放数据的是每个线程中的ThreadLocalMap。所以ThreadLocal一般应该定义成静态变量。****

也不是一般人认为的Key是线程的名字或者标识

实现

public class ThreadLocal<T> {
  public T get() {
    // 获取当前线程
    Thread t = Thread.currentThread();
    // 从当前线程中获取ThreadLocalMap变量
    ThreadLocalMap map = getMap(t);
    if (map != null) {
      // 以当前的ThreadLocal对象作为Key,从Map中获取对应的值
      ThreadLocalMap.Entry e = map.getEntry(this);
      if (e != null)
        return (T)e.value;
    }
    return setInitialValue();
  }

  public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
      map.set(this, value);
    else
      createMap(t, value);
    }
      
    ThreadLocalMap getMap(Thread t) {
      return t.threadLocals;
    }
}

public class Thread implements Runnable {
  // 每个线程都有一个ThreadLocalMap对象
  ThreadLocal.ThreadLocalMap threadLocals = null;
}

应用

  1. 避免同步或每次使用都创建新对象
    针对Random、DateFormatter等非线程安全类,实现每个线程一个对象
    数据库连接等资源限制类,实现每个线程一个连接

  2. 线程内跨方法的数据传递
    例如Hibernate的Session绑定(实现延迟加载和事务处理,保证整个处理过程使用同一个session)

推荐阅读更多精彩内容

  • 转载:http://www.codeceo.com/article/java-threadlocal-deep-l...
    Jannonx阅读 217评论 0 3
  • ThreadLocal提供了线程本地变量,它可以保证访问到的变量属于当前线程,每个线程都保存有一个变量副本,每个线...
    FX_SKY阅读 2,779评论 0 1
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 30,861评论 10 321
  • Java-ThreadLocal 参考 A Painless Introduction to Java's Thr...
    xiaofudeng阅读 81评论 1 0
  • 今天用两点透视画字母偶的作品: 画的太扁,不好看!前几天有朋友希望我能上过程图,那就把我临摹的过程图上一下,看看是...
    friendly99阅读 350评论 7 13