06.12 「javaSE基礎」2018面試-多線程之局部變量ThreadLocal的案例演示

今天主要寫一下ThreadLocal對象。文章如有介紹不全的,望多加體諒。

  • ThreadLocal的作用和目的:用於實現線程內的數據共享,即對於相同的程序代碼,多個模塊在同一個線程中運行時要共享一份數據,而在另一個線程運行時又共享另外一份數據。
  • 每個線程調用全局ThreadLocal對象的set方法,在set方法中,首先根據當前線程獲取當前線程的ThreadLocal對象,然後往這個map中插入一條記錄,key其實就是ThreadLocal對象,value就是各自的set方法傳進去的值。也就是每個線程其實都有一份各自獨有的ThreadLocalMap對象,該對象的key是ThreadLocal對象,值是用戶設置的具體值。該線程結束可以調用ThreadLocal.remove()方法,這樣會更快的釋放內存,不調用也可以,因為線程結束後可以自動釋放相關的ThreadLocal變量。

ThreadLocal的應用場景:

  1. 訂單處理包含一系列操作:減少庫存量、增加流水臺賬、修改總賬,這幾個操作要在同一個事務中完成,通常也即是在同一個線程中處理,如果累加公司應收款的操作失敗了,應該把前面的操作回滾,否則提交所有操作,這要求這些操作使用相同的數據庫連接對象,而這些操作的代碼分別位於不同的模塊類中。
  2. 銀行轉賬包含一系列操作:把轉出的賬戶餘額減少,把轉入賬戶的餘額增加,這兩個操作都要在一個事務中完成,它們必須使用相同的數據庫連接對象,轉入和轉出操作的代碼分別是兩個不同的賬戶對象的方法。
  3. 例如Strut2的ActionContext,同一段代碼被不同的線程調用運行時,該代碼操作的數據是每個線程各自的狀態和數據,對於不同的線程來說,getContext方法拿到的對象都不相同,對於同一個線程來說,不管調用getContext方法多少次和在哪個模塊的getContext方法,拿到的都是同一個。

ThreadLocal的使用方式:

1.在關聯數據類中創建private static ThreadLocal。在下圖的例子中,私有靜態ThreadLocal實例(serialNum)為調用該類的靜態SerialNum.get()方法的每個線程維護了一個“序列號”,該方法返回當前線程的序列號。(線程的序列號在第一次調用SerialNum.get()方法時分配,並在後續的調用中不會更改。)

「javaSE基礎」2018面試-多線程之局部變量ThreadLocal的案例演示

案例一

「javaSE基礎」2018面試-多線程之局部變量ThreadLocal的案例演示

案例二

2.在Rannable中創建ThreadLocal。

在線程內部創建ThreadLocal,基本步驟如下:

  • 在多線程類(如下例子ThreadLocalTest1)中,創建一個ThreadLocal對象threadXxx,用來保存線程間需要間隔處理的對象xxx;
  • 在ThreadLocalTest1類中,創建一個需要隔離訪問的數據的方法getXxx(),在方法中判斷,若ThreadLocal對象為null時,應該new()一個隔離訪問類型的對象,並強制轉換為要應用的類型;
  • 在ThreadLocalTest1類的run()方法中,通過調用getXxx()方法獲取需要操作的數據,這樣可以保證每個線程對應一個數據對象,在任何時刻都操作的是這個對象。
「javaSE基礎」2018面試-多線程之局部變量ThreadLocal的案例演示

案例3

「javaSE基礎」2018面試-多線程之局部變量ThreadLocal的案例演示

案例3運行結果

下一篇還將以案例展示多線程數據共享實例。感謝關注轉發。

「javaSE基礎」2018面試-多線程之局部變量ThreadLocal的案例演示


分享到:


相關文章: