1. 程式人生 > >Java併發程式設計-ThreadLocal

Java併發程式設計-ThreadLocal

一、ThreadLocal 的理解

ThreadLocal 由 JDK 包提供,它提供了執行緒本地變數,如果建立了一個 ThreadLocal 變數,那麼訪問這個變數的每個執行緒都會有這個變數的一個本地副本。當多個執行緒操作這個變數的時候,實際上是操作自己本地記憶體裡面的變數,從而避免了執行緒安全問題。建立了一個 ThreadLocal 變數後,每個執行緒都會複製一個變數到自己的本地記憶體中。如圖所示:

ThreadLocal01.png

二、ThreadLocal 的使用示例

程式碼如下:

public class ThreadLocalTest {
    
    // 建立ThreadLocal變數
    public static ThreadLocal<String> localVariable = new ThreadLocal<>();
    
    // 列印方法
    public static void print(String str) {
        // 列印當前執行緒本地記憶體中localVariable變數的值
        System.out.println(str + ":" + localVariable.get());
        // 清除當前執行緒本地記憶體中localVariable變數的值
        localVariable.remove();
    }
    
    public static void main(String[] args) {
        
        // 建立執行緒thread1
        Thread thread1 = new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                // 設定執行緒thread1中本地變數localVariable的值
                localVariable.set("thread1 local variable");
                print("thread1");
                System.out.println("thread1 remove after" + ":" + localVariable.get()); 
            }
        });
        
        // 建立執行緒thread2
        Thread thread2 = new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                // 設定執行緒thread2中本地變數localVariable的值
                localVariable.set("thread2 local variable");
                print("thread2");
                System.out.println("thread2 remove after" + ":" + localVariable.get());
            }
        });
        
        // 啟動執行緒
        thread1.start();
        thread2.start();
        
    }

}

執行結果如下:

thread1:thread1 local variable
thread2:thread2 local variable
thread1 remove after:null
thread2 remove after:null

將 print() 方法中的 localVariable.remove() 註釋,再次執行得到執行結果:

thread1:thread1 local variable
thread2:thread2 local variable
thread1 remove after:thread1 local variable
thread2 remove after:thread2 local variable