Java高並發程式設計(九)--ThreadLocal

來源:互聯網
上載者:User

標籤:例子   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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.