JAVA中ThreadLocal用法介紹

概述

ThreadLocal看名字好像是一個Thread的實現,其實並非這樣的,ThreadLocal並不是是一個線程的本地實現版本,它並非一個Thread,而是線程局部 (thread-local) 變量。這些變量不一樣於它們的普通對應物,由於訪問某個變量(經過其 get 或 set 方法)的每一個線程都有本身的局部變量,它獨立於變量的初始化副本。ThreadLocal 實例一般是類中的 private static 字段,它們但願將狀態與某一個線程(例如,用戶 ID 或事務 ID)相關聯。java

線程局部變量其實的功用很是簡單,就是爲每個使用該變量的線程都提供一個變量值的副本,是Java中一種較爲特殊的線程綁定機制,使每個線程均可以獨立地改變本身的副本,而不會和其它線程的副本衝突。多線程

從線程的角度看,每一個線程都保持一個對其線程局部變量副本的隱式引用,只要線程是活動的而且 ThreadLocal 實例是可訪問的;在線程消失以後,其線程局部實例的全部副本都會被垃圾回收(除非存在對這些副本的其餘引用)。併發

API

構造方法摘要

方法名 說明
ThreadLocal() 建立一個線程本地變量

方法摘要

返回值 方法名 說明
T get() 返回此線程局部變量的當前線程副本中的值
protected T initialValue() 返回此線程局部變量的當前線程的「初始值」
void remove() 移除此線程局部變量當前線程的值
void set(T value) 將此線程局部變量的當前線程副本中的值設置爲指定值

使用示例

import java.util.Random;

/**
 * ThreadLocal測試
 * 
 * @author jianggujin
 * 
 */
public class ThreadLocalDemo implements Runnable
{
   private final static ThreadLocal<People> threadLocal = new ThreadLocal<People>();

   public static void main(String[] agrs)
   {
      ThreadLocalDemo td = new ThreadLocalDemo();
      Thread t1 = new Thread(td);
      Thread t2 = new Thread(td);
      t1.start();
      t2.start();
   }

   public void run()
   {
      accessStudent();
   }

   public void accessStudent()
   {
      // 獲取當前線程的名字
      String currentThreadName = Thread.currentThread().getName();
      System.out.println(currentThreadName + " is running!");
      // 產生一個隨機數並打印
      Random random = new Random();
      int age = random.nextInt(100);
      System.out.println("thread " + currentThreadName + " set age to:" + age);
      People people = getPeople();
      people.setAge(age);
      System.out.println("thread " + currentThreadName + " first read age is:"
            + people.getAge());
      try
      {
         Thread.sleep(500);
      }
      catch (InterruptedException ex)
      {
         ex.printStackTrace();
      }
      System.out.println("thread " + currentThreadName + " second read age is:"
            + people.getAge());
   }

   protected People getPeople()
   {
      People people = threadLocal.get();
      // 線程首次執行此方法的時候,threadLocal.get()確定爲null
      if (people == null)
      {
         // 建立一個對象,並保存到本地線程變量threadLocal中
         people = new People();
         threadLocal.set(people);
      }
      return people;
   }
}

class People
{
   private int age = 0;

   public int getAge()
   {
      return this.age;
   }

   public void setAge(int age)
   {
      this.age = age;
   }
}

總結

ThreadLocal使用場合主要解決多線程中數據數據因併發產生不一致問題。ThreadLocal爲每一個線程的中併發訪問的數據提供一個副本,經過訪問副原本運行業務,這樣的結果是耗費了內存,可是大大減小了線程同步所帶來性能消耗(空間換時間),也減小了線程併發控制的複雜度。dom

相關文章
相關標籤/搜索