zoukankan      html  css  js  c++  java
  • ThreadLocal独家解秘 附JDK源码

    public class ThreadLocalTest {

    ThreadLocal<String> tl = new ThreadLocal<String>();

    ThreadLocal<String> t2 = new ThreadLocal<String>();

    /**
    * @author zlz
    *
    * @time 2013-7-11上午10:14:50
    * @param args
    */
    public static void main(String[] args) {

    ThreadLocalTest tlt = new ThreadLocalTest();
    tlt.t2.set("Main Thread 2");

    tlt.tl.set("Main Thread");

    Thread t = new Thread(new Runnable() {

    @Override
    public void run() {
    ThreadLocalTest tlt = new ThreadLocalTest();
    tlt.tl.set("Child Thread Local 1");
    tlt.tl.set("Child Thread Local 2");
    System.out.println("Child Thread ID:"
    + Thread.currentThread().getId() + "---" + tlt.tl.get());
    }
    });
    t.start();
    try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }


    System.out.println("Main Thread ID:" + Thread.currentThread().getId()
    + "---" + tlt.t2.get());
    System.out.println("Main Thread ID:" + Thread.currentThread().getId()
    + "---" + tlt.tl.get());

    }

    }
      执行结果:
    Child Thread ID:11---Child Thread Local 2
    Main Thread ID:1---Main Thread 2
    Main Thread ID:1---Main Thread

    子线程的值改变后不会影响主线程
    单一线程内多次赋值,则最后一次生效


    结论:
    ThreadLocal 结构如下
    Thread类中有对象 ThreadLocal.ThreadLocalMap<ThreadLocal,Object>
    ThreadLocal通过 Thread.CurrentThread获取对应的ThreadLocalMap对象
    ThreadLocal本身就是一个变量,他只能有一个值。多次赋值则最后一次生效.
    JDK源码:

    public class ThreadLocal<T> {
    ...
    ...
    ...
        /**
         * Returns the value in the current thread's copy of this
         * thread-local variable.  If the variable has no value for the
         * current thread, it is first initialized to the value returned
         * by an invocation of the {@link #initialValue} method.
         *
         * @return the current thread's value of this thread-local
         */
        public T get() {
            Thread t = Thread.currentThread();
            //先通过当前线程获取threadLocalMap
            ThreadLocalMap map = getMap(t);
            if (map != null) {
                //再通过当前threadLocal对象this获取值
                ThreadLocalMap.Entry e = map.getEntry(this);
                if (e != null)
                    return (T)e.value;
            }
            return setInitialValue();
        }

    ThreadLocalMap getMap(Thread t) {
            return t.threadLocals;
        }
    ...
    }

    publicclass Thread implements Runnable
    {
      ThreadLocal.ThreadLocalMap threadLocals = null;
    }
  • 相关阅读:
    hdu 1325 判断有向图是否为树
    poj 1182
    Ubuntu 系统 文件操作命令
    vim 快捷键大全
    Git 上传本地命令
    git错误:fatal: Not a git repository (or any of the parent directories): .git
    Git 如何回到过去,然后 再 回到将来
    Git 提供篇
    Linux 的cp命令
    Linux :: vi E212: Can't open file for writing
  • 原文地址:https://www.cnblogs.com/hiaming/p/8967804.html
Copyright © 2011-2022 走看看