成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用ThreadLocal來優化下代碼吧

開發
今天給大家介紹用ThreadLocal來優化下代碼

                            [[344746]]

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

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

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

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

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

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

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

  • 什么是ThreadLocal
  • 如何使用ThreadLocal優化userid層層傳遞的問題
  • ThreadLocal原理是啥
  • ThreadLocal的實戰要點

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

簡單翻譯過來,就是說:

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

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

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

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


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

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

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

源碼如下所示。

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

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

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

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

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

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

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

主要三步:

獲取當前線程

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

3.2 ThreadLocalMap是什么。
ThreadLocalMap是一個定義在ThreadLocal類內部的靜態類,里面還定義了一個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.實戰要點
在一開始的優化設計中,不知道大家有沒有注意到對ThreadLocal的remove調用。

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

4.1 避免內存泄露

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

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

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

在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優化任務

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

2021-05-26 08:02:03

ThreadLocal多線程多線程并發安全

2020-01-22 16:46:04

Python 開發編程語言

2010-04-16 10:42:10

Oracle存儲過程

2019-08-30 20:50:19

戴爾

2022-05-09 07:27:50

ThreadLocaJava

2022-04-11 00:06:19

開發服務架構

2015-05-04 11:26:52

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久国产视频| 中文字幕1区 | 国产精品久久久久久婷婷天堂 | 久久久久久高潮国产精品视 | 精品欧美一区二区三区久久久 | 免费亚洲一区二区 | 国产a视频 | 不卡的av电影 | 在线观看成人 | 国产日韩精品视频 | 丝袜美腿一区 | 视频第一区| 一级一级一级毛片 | 午夜精品久久久久久久99黑人 | 精品亚洲一区二区三区 | 激情六月丁香婷婷 | 欧美性tv| 99九色| 日本淫视频| 91亚洲国产成人久久精品网站 | 天堂资源最新在线 | 啪啪综合网 | 亚洲综合视频一区 | 欧美精品一区二区三区在线四季 | 国产一级影片 | 韩日有码 | 亚洲免费一区 | 欧美激情 亚洲 | 蜜月va乱码一区二区三区 | 黄网站涩免费蜜桃网站 | 草樱av| 超碰在线人人干 | 欧洲色综合 | 香蕉久久久久久 | 嫩草视频在线免费观看 | 国产 欧美 日韩 一区 | 免费黄色片在线观看 | 91免费电影| 日本一级淫片免费啪啪3 | 成人免费视频观看视频 | 国产一区二区三区在线看 |