码迷,mamicode.com
首页 > 编程语言 > 详细

Java高并发程序设计(九)--ThreadLocal

时间:2018-08-07 16:09:44      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:例子   col   and   super   adp   自己   current   system   value   

如果说锁是让线程有序的争夺资源的话,那么ThreadLocal就是让每个线程都有一份资源。

打个比方,锁是让一百个人争夺一只笔区写字,ThreadLocal就是一百个人每人都有一只笔,在轮到他们写字的时候写。

写个简单的例子:

public class demo implements Runnable{
    static ThreadLocal<test> tl=new ThreadLocal<test>();
    static class test 
    {
        private Integer in;
        public Integer getIn() {return in;}
        test(Integer in){this.in=in;}
    }
    public static void main(String[] args) {
        ExecutorService es=Executors.newFixedThreadPool(10);
        for(int i=0;i<100;i++)
        {
            es.submit(new demo());
        }
    }
    public void run() {
        tl.set(new test(new Random().nextInt(100)));
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(tl.get().getIn());
    }
}

Demo里有一个test内部类,有一百个线程,每个线程都有一个test类存在ThreadLocal那里,每个线程访问自己的test,互不影响。

 

接下来来看ThreadLocal的原理,从set()方法看起:

 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,ThreadLocalMap是它的内部类:

static class ThreadLocalMap {
        static class Entry extends WeakReference<ThreadLocal> {
            Object value;

            Entry(ThreadLocal k, Object v) {
                super(k);
                value = v;
            }
        }
、、、、、、、、、 }

可以把它看做和HashMap类似的东西,用ThreadLocal作为key,

然后进入getMap()方法:

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

直接获得线程的threadLocals,进入Thread,

ThreadLocal.ThreadLocalMap threadLocals = null;

可以看到Thread维护了一个ThreadLocal.ThreadLocalMap,回到set方法,现在我们知道getMap()获得一个有Thread维护的ThreadLocal内部类,现在它为空,进入else,进入createMap():

void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

给Thread中的threadLocals赋值,自己本身作为key,需要维护的值作为Value。

 

看完set方法,接下来看get()方法:

public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }

很简洁明了,从map里面获得value,没什么好说的,想了解更详细的可以自己看源码。

 

另外,因为threadLocals的引用是在Thread里面,Thread不退出,意味着它会一直存在,而且如果是由线程池维护线程,线程可能不会退出。

所以最好习惯性用完之后,调用remove()方法。

 

Java高并发程序设计(九)--ThreadLocal

标签:例子   col   and   super   adp   自己   current   system   value   

原文地址:https://www.cnblogs.com/blogofjzq/p/9437344.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!