Java并發編程之ThreadLocal類詳解

jopen 9年前發布 | 17K 次閱讀 Java開發 java并發
ThreadLocal類可以理解為ThreadLocalVariable(線程局部變量)提供了get與set等訪問接口或方法,這些方法為每個使用該變量的線程都存有一份獨立的副本,因此get總是返回當前執行線程在調用set時設置的最新值。可以將ThreadLocal<T>視為 包含了Map<Thread,T>對象,保存了特定于該線程的值。

概括起來說,對于多線程資源共享的問題,同步機制采用了以時間換空間的方式,而ThreadLocal采用了以空間換時間的方式。前者僅提供一份變量,讓不同的線程排隊訪問,而后者為每一個線程都提供了一份變量,因此可以同時訪問而互不影響。

模擬ThreadLocal

     import java.util.Collections;
    import java.util.HashMap;
    import java.util.Map;

    public class SimpleThreadLocal<T> {
    private Map<Thread, T> valueMap = Collections
    .synchronizedMap(new HashMap<Thread, T>());

    public void set(T newValue) {
    valueMap.put(Thread.currentThread(), newValue); // ①鍵為線程對象,值為本線程的變量副本
    }

    public T get() {
    Thread currentThread = Thread.currentThread();
    T o = valueMap.get(currentThread); // ②返回本線程對應的變量
    if (o == null && !valueMap.containsKey(currentThread)) { // ③如果在Map中不存在,放到Map中保存起來。
    o = initialValue();
    valueMap.put(currentThread, o);
    }
    return o;
    }

    public void remove() {
    valueMap.remove(Thread.currentThread());
    }

    protected T initialValue() {
    return null;
    }
    }

實用ThreadLocal
     class Count {
    private SimpleThreadLocal<Integer> count = new SimpleThreadLocal<Integer>() {
    @Override
    protected Integer initialValue() {
    return 0;
    }
    };

    public Integer increase() {
    count.set(count.get() + 1);
    return count.get();
    }

    }

    class TestThread implements Runnable {
    private Count count;

    public TestThread(Count count) {
    this.count = count;
    }

    @Override
    public void run() {
    // TODO Auto-generated method stub
    for (int i = 1; i <= 3; i++) {
    System.out.println(Thread.currentThread().getName() + "\t" + i
    + "th\t" + count.increase());
    }
    }
    }

    public class TestThreadLocal {
    public static void main(String[] args) {
    Count count = new Count();
    Thread t1 = new Thread(new TestThread(count));
    Thread t2 = new Thread(new TestThread(count));
    Thread t3 = new Thread(new TestThread(count));
    Thread t4 = new Thread(new TestThread(count));
    t1.start();
    t2.start();
    t3.start();
    t4.start();
    }
    }

輸出
Thread-0    1th    1
Thread-0    2th    2
Thread-0    3th    3
Thread-3    1th    1
Thread-1    1th    1
Thread-1    2th    2
Thread-2    1th    1
Thread-1    3th    3
Thread-3    2th    2
Thread-3    3th    3
Thread-2    2th    2
Thread-2    3th    3 
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!