自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用ThreadLocal來優(yōu)化下代碼吧

開發(fā)
今天給大家介紹用ThreadLocal來優(yōu)化下代碼

                            [[344746]]

 最近接手了一個老項目,看到一個很有意思的現象。

這個項目中大量的方法入參都會帶上user信息,比如這樣

它的意圖是希望在方法內使用user的信息,但是如此大范圍的傳遞用戶信息,第一感覺就是不優(yōu)雅。那有什么辦法可以優(yōu)化一下呢?

我們第一反應是,可以存一個全局變量,在初始位置將用戶信息存入全局變量,然后在需要的地方去get一下。

那在WEB應用中,每個請求都是一個獨立線程,怎么去標記呢?

可以用線程的id去作為map的key,將該請求的用戶信息作為map的value。

沒錯,Java已經幫我們封裝好了這么一個對象,它就是我們今天要說的ThreadLocal。

  • 什么是ThreadLocal
  • 如何使用ThreadLocal優(yōu)化userid層層傳遞的問題
  • ThreadLocal原理是啥
  • ThreadLocal的實戰(zhàn)要點

1.什么是ThreadLocal
先來看下JDK的注釋:

簡單翻譯過來,就是說:

  1. ThreadLocal提供了線程隔離的局部變量,通過get( )和set( )方法操作當前線程對應的變量,而且不會和其他線程沖突,實現了基于線程的數據隔離。 

2.如何使用ThreadLocal進行優(yōu)化
話不多說,基于我們開頭的例子,我迫不及待地用ThreadLocal來優(yōu)化一下。

2.1 構建基于ThreadLocal的上下文
定義一個SessionUser類,存儲用戶信息,包括用戶id、用戶名。

然后定義一個基于ThreadLocal的上下文SessionUserContext,代碼如下所示。


2.2 信息存入ThreadLocal中
在我們的優(yōu)化案例中,就是存入用戶信息。

解析請求中的用戶信息有很多方法。本文以HandlerIntercept為例,說明下MVC中的一種方式。

  • 實現HandlerIntercept接口
  • 重寫preHandler方法
  • 解析HttpServletRequest,獲取用戶信息
  • 用戶信息存于SessionUserContext

源碼如下所示。

2.3 在需要的地方獲取信息
原本需要傳入CurrentUser的參數都可以去掉了。

在需要用戶信息的時候,直接從SessionUserContext中獲取即可。

哈哈,是不是看起來一下子清爽了很多。

可以在任何地方獲取user信息,不再需要層層傳遞用戶信息了。

3.ThreadLocal實現原理
上面我們已經知道了怎么通過ThreadLocal進行優(yōu)化。

下面,我們要 知其然知其所以然,一起看看ThreadLocal實現原理吧。

3.1 set方法
Set方法應該是ThreadLocal的核心邏輯了。

主要三步:

獲取當前線程

  • 獲取ThreadLocalMap對象
  • 如果ThreadLocalMap對象存在,則將當前線程對象作為key,要存儲的對象作為value存到map中 如果ThreadLocalMap對象不存在,就調用creatMap( )進行創(chuàng)建

3.2 ThreadLocalMap是什么。
ThreadLocalMap是一個定義在ThreadLocal類內部的靜態(tài)類,里面還定義了一個Entry類作為存儲值的地方。

ThreadLocalMap的key是當前ThreadLocal對象,value是我們要存儲的值(對象)。

調用creatMap的時候,就是新建一個ThreadLocalMap對象

同時,ThreadLocalMap在Thread類中作為一個屬性存在。

每個線程Thread維護了ThreadLocalMap這么一個Map,這個map的key是LocalThread對象本身,value則是要存儲的對象

3.3 get方法
Get方法就比較簡單了,就是從map中取值的過程。

3.4 ThreadLocal小結
現在,讓我們重新梳理一遍,看看ThreadLocal是如何實現變量的線程隔離的:

每個Thread維護著一個ThreadLocalMap的引用

ThreadLocalMap是ThreadLocal的內部類,用Entry來進行存儲,key是ThreadLocal對象,值是傳遞進來的對象

調用ThreadLocal的get()/set()方法時,實際上就是以ThreadLocal對象為key,在ThreadLocalMap中讀寫value

4.實戰(zhàn)要點
在一開始的優(yōu)化設計中,不知道大家有沒有注意到對ThreadLocal的remove調用。

這里就需要談談ThreadLocal使用時的,兩個要點。尤其是在使用線程池的時候使用ThreadLocal。

4.1 避免內存泄露

在ThreadLocalMap介紹的時候,我們可以看到,ThreadLocalMap是Thread的一個屬性。因此,ThreadLocalMap和Thread的生命周期是一樣的。

如果沒有手動刪除對應的ThreadLocal的key,那么就會造成內存泄漏無法回收。尤其在線程池環(huán)境下,線程會被不斷復用。

4.2 線程池避免重復線程變量影響
以上文優(yōu)化案例為例。

在MVC中,每次請求進來會使用線程池復用線程。如果請求帶了用戶信息,那么就會重置ThreadLocal對應的用戶信息,如果請求沒有帶用戶信息,必須手動清除一下當前ThreadLocal對應的變量,否則后面使用過程中可能會造成混亂。

 

責任編輯:姜華 來源: 阿丸筆記
相關推薦

2016-11-22 16:34:11

githubgit前端

2011-12-26 09:34:26

2020-05-20 09:47:57

程序員代碼網絡

2020-12-07 05:50:54

print()Python代碼

2019-12-17 08:45:30

ifelseJava

2010-03-04 16:33:21

Ubuntu cvs

2024-05-11 18:48:40

技巧代碼技能

2020-12-04 07:49:54

AICtrl C代碼

2023-01-05 13:36:41

Script優(yōu)化任務

2019-09-12 08:38:15

機器學習電影數據庫

2021-01-15 05:16:37

Vue3開源代碼量

2018-02-02 10:12:57

谷歌開源 TensorFlow

2024-10-28 08:15:32

2020-01-22 16:46:04

Python 開發(fā)編程語言

2021-05-26 08:02:03

ThreadLocal多線程多線程并發(fā)安全

2010-04-16 10:42:10

Oracle存儲過程

2022-05-09 07:27:50

ThreadLocaJava

2018-05-28 07:27:18

2019-08-30 20:50:19

戴爾

2015-05-04 11:26:52

點贊
收藏

51CTO技術棧公眾號