java併發編程學習之ThreadLocal

用途

本地線程,一般用於防止對可變的單實例對象或全局變量進行共享,常見的好比數據庫鏈接。能夠將ThreadLocal<T>視爲Map<Thread,T>,雖然實際上並非這樣實現的。也能夠把事務上下文保存在ThreadLocal中,雖然方便處理一些功能,可是隱性增長了耦合度,下降了代碼的可重用性,所以儘可能避免濫用ThreadLocal。ThreadLocal提供了get和set經常使用的方法,set是用來設置值,get是用來獲取set設置的最新的值。這些值相對於使用改變量的線程存有的一份獨立的副本。java

例子

public class NotSafeDemo2 {
    private ThreadLocal<Integer> num = new ThreadLocal<>();

    public void add(int value) {
        try {
            if (null == num.get()) {
                num.set(0);
            }
            int temp = num.get();
            num.set(num.get() + value);
            Thread.sleep(100);
            System.out.println(value + "+" + temp + "=" + num.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        NotSafeDemo2 synchronizeDemo = new NotSafeDemo2();
        AddThread3 addThread3 = new AddThread3(synchronizeDemo);
        AddThread4 addThread4 = new AddThread4(synchronizeDemo);
        addThread3.start();
        addThread4.start();
    }
}

class AddThread3 extends Thread {
    NotSafeDemo2 synchronizeDemo;

    public AddThread3(NotSafeDemo2 synchronizeDemo) {
        this.synchronizeDemo = synchronizeDemo;
    }

    @Override
    public void run() {
        synchronizeDemo.add(1);

    }
}

class AddThread4 extends Thread {
    NotSafeDemo2 synchronizeDemo;

    public AddThread4(NotSafeDemo2 synchronizeDemo) {
        this.synchronizeDemo = synchronizeDemo;
    }

    @Override
    public void run() {
        synchronizeDemo.add(2);
    }
}

運行結果以下:
clipboard.png
這裏直接更改java併發編程學習之synchronize(一)的例子,能夠看到,num的值不被線程共享。數據庫

相關文章
相關標籤/搜索