• ThreadLocal


    介绍

    ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

    ThreadLocal像是一个map,map的键就是每一个线程,值就是变量副本

    使用

    public class ThreadLocalDemo {
        private ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);
    
        public Integer getNext() {
            Integer integer = threadLocal.get();
            threadLocal.set(++integer);
            return integer;
        }
    
        public static void main(String[] args) {
            ThreadLocalDemo threadLocalDemo = new ThreadLocalDemo();
            for (int i = 0; i < 3; i++) {
                new Thread(() -> {
                    while (true) {
                        System.out.println(Thread.currentThread().getName() + threadLocalDemo.getNext());
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        }
    }
    

    上面的代码中,每一个线程的值都是从0开始递增,各个线程之间互不影响。

    原理解析

    首先查看get()方法的源代码:

    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                // 这里可以看到最终的值是从这里拿到的,也就是说值会存在ThreadLocal下面的ThreadLocalMap里面的Entry里面的value里面	
                T result = (T)e.value;    
                return result;
            }
        }
        return setInitialValue();
    }
    
    
    private T setInitialValue() {
        T value = initialValue();   // 获取初始值 这个是用户自己重写的
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }
    
    void createMap(Thread t, T firstValue) {
        // 这个创建ThreadLocalMap的方法比较有趣的是它将创建好后的map赋值给了当前线程的一个属性
     	// 而在Thread类中确实有这样一个属性,如下。因此ThreadLocalMap是属于每一个线程的
        t.threadLocals = new ThreadLocalMap(this, firstValue);   
    }
    
    ThreadLocal.ThreadLocalMap threadLocals = null;
    
  • 相关阅读:
    使用C39HrP48DhTt字體生成條型碼
    GUI設計禁忌
    music
    AADL的四种经典设计模式
    Model to Text工具Acceleo使用教程(七)——模板服务
    Model to Text工具Acceleo使用教程(二)——体系结构
    Model to Text工具Acceleo使用教程——背景知识
    P/NP/NPC/NPhard概念的图形解释
    哥德巴赫猜想穷举验证算法及实现
    Model to Text工具Acceleo使用教程(五)——模板服务
  • 原文地址:https://www.cnblogs.com/Myarticles/p/12046042.html
Copyright © 2020-2023  润新知