有必要澄清一下究竟TLS的做用是什麼?

OSCHINA上看到了好幾篇帖子在介紹Java的ThreadLocal類,可是,說到該類的做用是,居然一致的都和線程的同步/互斥扯上關係,將其劃做與Synchronized功能同樣的,用來解決多線程間併發訪問共享資源的一種方式。 以爲實在有必要澄清一下,下面彙總了我回的一些內容,做爲澄清。 java

首先Java的ThreadLocal本質上就是TLS(Thread Local Storage),因此TLS的做用到底是什麼那? linux

不要因爲java混淆了本質,其實就是TLS的概念,去問問搞linux的前輩,TLS的目的是爲了線程同步和互斥?徹底不一樣的概念 安全

簡直誤人子弟,我在OSCHINA看到兩篇關於ThreadLocal的文檔了,都是說「ThreadLocal是解決線程安全問題一個很好的思路,它經過爲每一個線程提供一個獨立的變量副本解決了變量併發訪問的衝突問題」。 TLS(Thread Local Storage) 是爲了解決線程安全和併發訪問共享資源的目的?! 線程互斥技術是爲了解決,多個線程間共享的,你們都要訪問和讀寫的資源,如何在線程併發時不會有問題,典型的打印機問題!注意,這裏的資源,是須要在多個線程間共享的! 而TLS到底是解決什麼問題那? TLS解決了這樣一個需求,就是但願在一個/每一個線程的線程上下文/環境下執行的任何實體(函數,組件等)內,都能訪問某一個變量。 那麼很明顯,這個變量是須要作成全局的,可是,普通全局的會污染別的線程。因此,此時須要TLS。 舉個最簡單的例子,假設個人程序會連續啓動6個線程去建立文件,線程代碼是徹底同樣的。那麼,我就可使用TLS來記錄線程上下文中的文件句柄。此時,我使用一致的文件操做代碼,卻能保證無論在任何實體中操做的文件句柄,都自動的是當前線程下的打開文件的文件句柄 TLS更多的是用來存儲線程上下文相關的信息,使得在一致的代碼中,自動訪問差別性的線程綁定的上下文相關信息 對TLS更簡單的,可是更直觀的理解能夠以下(基於C語言): 1. 全局對象,全局變量的做用域和生命週期是全局的,這裏的全局是指進程範疇,也就是說,若是你將其設計爲全局對象,全局變量,就意味着你但願在多線程的環境中,仍然能共享和訪問。 全局對象,全局變量不是說不讓多線程來訪問,而是說有的時候不指望他們同時訪問,此時引入了線程的互斥,互斥的後果是保證不一樣時訪問,可是,並無改變共享的本質! 2. 若是設計的時候,就但願將某個對象,變量設計爲線程局部的,那典型的是能夠將其設計爲函數的局部變量。 但是,我若是又但願在線程執行時,任意的函數和對象裏面均可以訪問到它那?! 此時,可能會想到用全局對象,全局變量,可是,它又會使得這種訪問域上升到進程級別,其實,我只是想在線程局部環境中,全局訪問該對象。 此時TLS應運而生,TLS就是達到了這種, 在線程局部環境(或者稱呼爲線程執行環境,線程上下文)下能夠全局訪問的對象/變量。 關於TLS的實際應用,更多的是定義一個TLS對象來存儲一些線程上下文相關的信息。 給你取這樣一個典型的例子吧,你能夠看到TLS實際的應用場合。 在一個支持單進程,多線程的輕量級移動平臺中,假設我實現了一個APP Framework,每個APP單獨運行在一個獨立的線程中,APP運行時關聯了不少信息,好比打開的文件,引用的組件,啓動的Timer等等。我但願框架能實現自動垃圾回收,什麼概念,就會應用退出的時候,即使應用沒有主動釋放打開的文件句柄,沒有主動cancel Timer,沒有主動釋放組件的引用,框架也能夠自動完成這些收尾工做,不然,後果是不堪想象的。 好了,假設應用的退出是調用了框架的 ExitApp API, 該API容許應用調用後關閉本身,也容許關閉別的應用。 那麼,假設該API觸發了應用的退出,最終調用到框架的App_CleanUp函數,那麼App_CleanUp函數除了完成應用自己實例的釋放外,確定是在這裏來完成咱們上面說的收尾工做,怎麼來作哪?! 很明顯,這裏典型的,就可使用TLS了。具體以下: 在Framework的API中,當應用的線程啓動時,New 一個AppContext的對象或者結構體,而後將對象的指針或者結構體的指針以TLS的方式存儲起來。 AppContext內部包含了文件句柄,timer引用,組件引用等等。 而後,後續任何框架的文件操做/Timer操做時,取當前線程的TLS,而後轉換成AppContext後,將更新的文件句柄,timer引用等更新入AppContext對象內部。  而後,應用退出時,獲取TLS,而後轉換成AppContext,取出非空的文件句柄,組件引用,Timer引用等,來完成Cancel和Close操做。 其餘不想說了,若是你能明白這個實際的例子,你就能夠明白TLS的用途了。 上述的例子,來源於BREW/BMP框架內部的實際實現,固然有差異,可是思想是同樣的
相關文章
相關標籤/搜索