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

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

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

                            [[344746]]

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

這個項目中大量的方法入?yún)⒍紩蟯ser信息,比如這樣

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

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

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

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

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

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

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

簡單翻譯過來,就是說:

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

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

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

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


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

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

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

源碼如下所示。

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

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

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

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

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

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

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

主要三步:

獲取當前線程

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

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

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

調(diào)用creatMap的時候,就是新建一個ThreadLocalMap對象

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

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

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

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

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

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

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

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

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

4.1 避免內(nèi)存泄露

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

如果沒有手動刪除對應的ThreadLocal的key,那么就會造成內(nèi)存泄漏無法回收。尤其在線程池環(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

程序員代碼網(wǎng)絡

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

機器學習電影數(shù)據(jù)庫

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存儲過程

2019-08-30 20:50:19

戴爾

2022-05-09 07:27:50

ThreadLocaJava

2018-05-28 07:27:18

2022-04-11 00:06:19

開發(fā)服務架構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天在线操 | 久久久久久久久中文字幕 | 日本在线观看视频 | 亚洲国产日韩欧美 | 一本色道精品久久一区二区三区 | 久久狠狠 | 欧美精品一区在线发布 | 国产精品一区二区久久 | 久久综合伊人一区二区三 | 亚洲一区免费在线 | 亚洲精品久久久久久一区二区 | 精品久久久久久久久久 | 成人h动漫亚洲一区二区 | 九九免费 | 日韩电影免费在线观看中文字幕 | 亚洲一区二区视频在线播放 | 国产精品亚洲综合 | 欧美久久影院 | 久久久国产亚洲精品 | 日韩福利 | 在线一区视频 | 亚洲视频在线免费观看 | 日韩综合在线播放 | av手机在线免费观看 | 九色 在线 | 欧美一区二区三区在线看 | 国产成人精品一区二 | 国产精品视频网站 | 亚洲精品一区二区网址 | 成人在线观看免费 | 日韩视频精品在线 | 亚洲 中文 欧美 日韩 在线观看 | 91免费在线 | 国产精品美女久久久久久久久久久 | 区一区二在线观看 | 成人不卡 | 精品一区av| 国产乱码精品1区2区3区 | 亚洲成人网在线观看 | 日韩在线观看网站 | 麻豆一区二区三区精品视频 |