ThreadLocal 原理

ThreadLocal 原理及内存泄露 从源码看 ThreadLocal 实现原理及其内存泄露分析

未命名文件.png
每个 Thread 都有一个 ThreadLocalMap 成员变量.

为什么不是一个 ThreadLocal 维护一个 ThreadMap 呢?
想法:
如果 ThreadLocal 维护 ThreadMap, 那么这个 ThreadMap 需要是线程安全的, 要处理并发问题.
而 Thread 的 ThreadLocalMap 因为所有操作都在当前线程, 巧妙的避开了并发问题, 所以没有线程安全问题!
所以 Thread 维护 ThreadLocalMap 不用考虑并发.

Image.png

如果自己实现一个 ThreadLocal

  1. public class MyThreadLocal {
  2. private static Map<Thread, String> threadMap = new HashMap<>(); // 这个是有线程安全问题的!
  3. private static Map<Thread, String> threadMap = new ConcurrentHashMap<>(); // 这个是线程安全的, 但是效率低
  4. public void set(String value) {
  5. threadMap.put(Thread.currentThread(), value);
  6. }
  7. public String get() {
  8. return threadMap.get(Thread.currentThread());
  9. }
  10. private static MyThreadLocal threadLocal = new MyThreadLocal();
  11. public static void main(String[] args) {
  12. while (true) {
  13. new Thread(() -> {
  14. String uuid = UUID.randomUUID().toString();
  15. threadLocal.set(uuid); // set
  16. try {
  17. Thread.sleep(1);
  18. } catch (Exception e) {
  19. System.out.println(e.getMessage());
  20. }
  21. String uuid2 = threadLocal.get(); // get
  22. if (!uuid.equals(uuid2)) { // 比较
  23. System.out.println("Not Equal! 1: " + uuid + " 2: " + uuid2);
  24. }
  25. }).start();
  26. }
  27. }
  28. }

创建有初始值的 ThreadLocal

ThreadLocal<Object> threadLocal = new ThreadLocal<Object>(){
    @Override
    protected Object initialValue() {
        return new Object();
    }
};

ThreadLocal<Object> threadLocal = ThreadLocal.withInitial(Object::new);