多線程的目的
為什么要使用多線程?可以簡單的分兩個方面來說:
在多個cpu核心下,多線程的好處是顯而易見的,不然多個cpu核心只跑一個線程其他的核心就都浪費了;
即便不考慮多核心,在單核下,多線程也是有意義的,因為在一些操作,比如IO操作阻塞的時候,是不需要cpu參與的,這時候cpu就可以另開一個線程去做別的事情,等待IO操作完成再回到之前的線程繼續(xù)執(zhí)行即可。
多線程帶來的問題
其實多線程根本的問題只有一個:線程間變量的共享
java里的變量可以分3類:
類變量(類里面static修飾的變量)
實例變量(類里面的普通變量)
局部變量(方法里聲明的變量)
下圖是jvm的內(nèi)存區(qū)域劃分圖:
根據(jù)各個區(qū)域的定義,我們可以知道:
類變量 保存在“方法區(qū)”
實例變量 保存在“堆”
局部變量 保存在 “虛擬機(jī)?!?/p>
“方法區(qū)”和“堆”都屬于線程共享數(shù)據(jù)區(qū),“虛擬機(jī)?!睂儆诰€程私有數(shù)據(jù)區(qū)。
因此,局部變量是不能多個線程共享的,而類變量和實例變量是可以多個線程共享的。事實上,在java中,多線程間進(jìn)行通信的唯一途徑就是通過類變量和實例變量。
也就是說,如果一段多線程程序中如果沒有類變量和實例變量,那么這段多線程程序就一定是線程安全的。
以Web開發(fā)的Servlet為例,一般我們開發(fā)的時候,自己的類繼承HttpServlet之后,重寫doPost()、doGet()處理請求,不管我們在這兩個方法里寫什么代碼,只要沒有操作類變量或?qū)嵗兞?,最后寫出來的代碼就是線程安全的。如果在Servlet類里面加了實例變量,就很可能出現(xiàn)線程安全性問題,解決方法就是把實例變量改為ThreadLocal變量,而ThreadLocal實現(xiàn)的含義就是讓實例變量變成了“線程私有”的,即給每一個線程分配一個自己的值。
現(xiàn)在我們知道:其實多線程根本的問題只有一個:線程間變量的共享,這里的變量,指的就是類變量和實例變量,后續(xù)的一切,都是為了解決類變量和實例變量共享的安全問題。
如何安全的共享變量
現(xiàn)在唯一的問題就是要讓多個線程安全的共享變量(下文中的變量一般特指類變量和實例變量),上文提到了一種ThreadLocal的方式,其實這種方式并不是真正的共享,而是為每個線程分配一個自己的值。
延伸閱讀
- ssh框架 2016-09-30
- 阿里移動安全 [無線安全]玩轉(zhuǎn)無線電——不安全的藍(lán)牙鎖 2017-07-26
- 消息隊列NetMQ 原理分析4-Socket、Session、Option和Pipe 2024-03-26
- Selective Search for Object Recognition 論文筆記【圖片目標(biāo)分割】 2017-07-26
- 詞向量-LRWE模型-更好地識別反義詞同義詞 2017-07-26
- 從棧不平衡問題 理解 calling convention 2017-07-26
- php imagemagick 處理 圖片剪切、壓縮、合并、插入文本、背景色透明 2017-07-26
- Swift實現(xiàn)JSON轉(zhuǎn)Model - HandyJSON使用講解 2017-07-26
- 阿里移動安全 Android端惡意鎖屏勒索應(yīng)用分析 2017-07-26
- 集合結(jié)合數(shù)據(jù)結(jié)構(gòu)來看看(二) 2017-07-26