Java ThreadLocal示例及使用方法總結


一、概述

ThreadLocal的名稱比較容易讓人誤解,會認為其是一個“本地線程”。其實,ThreadLocal並不是一個Thread,而是Thread的局部變量。

其設計的初衷是為了解決多線程編程中的資源共享問題。提起這個,大家一般會想到synchronized,synchronized采取的是“以時間換空間”的策略,本質上是對關鍵資源上鎖,讓大家排隊操作。而ThreadLocal采取的是“以空間換時間”的思路,為每個使用該變量的線程提供獨立的變量副本,在本線程內部,它相當於一個“全局變量”,可以保證本線程任何時間操縱的都是同一個對象。

 二、實例

下面用一個實例闡述ThreadLocal的使用方法

創建一個Context類,其中含有transactionId屬性。 

 1 package com.vigar;
2
3 public class Context {
4
5 private String transactionId = null;
6
7 public String getTransactionId() {
8 return transactionId;
9 }
10
11 public void setTransactionId(String transactionId) {
12 this.transactionId = transactionId;
13 }
14 }

 

創建MyThreadLocal做為容器,將一個Context對象保存於ThreadLocal中

 1 package com.vigar;
2
3 public class MyThreadLocal {
4 public static final ThreadLocal userThreadLocal = new ThreadLocal();
5 public static void set(Context user) {
6 userThreadLocal.set(user);
7 }
8
9 public static void unset() {
10 userThreadLocal.remove();
11 }
12
13 public static Context get() {
14 return (Context)userThreadLocal.get();
15 }
16 }

 

多線程客戶端程序,用於測試

 1 package com.vigar;
2
3 import java.util.Random;
4
5 public class ThreadLocalDemo extends Thread {
6
7 public static void main(String[] args) {
8 Thread threadOne = new ThreadLocalDemo();
9 threadOne.start();
10 Thread threadTwo = new ThreadLocalDemo();
11 threadTwo.start();
12 }
13
14 @Override
15 public void run() {
16 // 線程
17 Context context = new Context();
18 Random random = new Random();
19 int age = random.nextInt(100);
20 context.setTransactionId(String.valueOf(age));
21
22 System.out.println("set thread ["+getName()+"] contextid to " + String.valueOf(age));
23 // 在ThreadLocal中設置context
24 MyThreadLocal.set(context);
25 /* note that we are not explicitly passing the transaction id */
26 try {
27 Thread.sleep(1000);
28 } catch (InterruptedException e)
29 {
30 e.printStackTrace();
31 }
32
33 new BusinessService().businessMethod();
34 MyThreadLocal.unset();
35 }
36 }

模擬業務層,在某處讀取context對象

1 package com.vigar;
2 public class BusinessService {
3 public void businessMethod() {
4 Context context = MyThreadLocal.get();
5 System.out.println(context.getTransactionId());
6 }
7 }

程序輸出:

 

set thread [Thread-0] contextid to 32
set thread [Thread-1] contextid to 89
32
89

三、總結
ThreadLocal使用步驟

1.建立ThreadLocal容器對象A,其中對需要保存的屬性進行封裝。並提供相應的get/set方法(全部為static)

2.在客戶端程序中,用A.setxxx, A.getXXX訪問相應數據,即可保證每個線程訪問的是自己獨立的變量

 
        

 參考文獻:

 1. http://lavasoft.blog.51cto.com/62575/51926/

 2. http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM