Java多執行緒中static變數的使用
阿新 • • 發佈:2021-02-10
技術標籤:java基礎
執行緒,是我們專案中繞不過的重點領域。提到執行緒,就常會聽到執行緒安全的術語。那什麼是執行緒安全呢?通俗點說,就是執行緒訪問時不產生資源衝突。其實,這是一個有點難以定義的概念,不是很容易讓人一聽就懂的概念。“一個類可以被多個執行緒安全呼叫就是執行緒安全的”《java程式設計併發實踐》。
來說說靜態變數、例項變數、區域性變數在多執行緒下的安全問題吧!
(一)靜態變數:執行緒非安全
1、靜態變數:使用static關鍵字定義的變數。static可以修飾變數和方法,也有static靜態程式碼塊。被static修飾的成員變數和成員方法獨立於該類的任何物件。也就是說,它不依賴類特定的例項,被類的所有例項共享。只要這個類被載入,Java虛擬機器就能根據類名在執行時資料區的方法區內定找到他們。因此,static物件可以在它的任何物件建立之前訪問,無需引用任何物件。
用public修飾的static成員變數和成員方法本質是全域性變數和全域性方法,當宣告它的類的物件時,不生成static變數的副本,而是類的所有例項共享同一個static變數。 2、靜態變數使用的場景: (1)物件間共享值時 (2)方便訪問變數時 3、靜態方法使用注意事項: (1)不能在靜態方法內使用非靜態變數,即不能直接訪問所屬類的例項變數; (2)不能在靜態方法內直接呼叫非靜態方法; (3)靜態方法中不能使用this和super關鍵字; 4、驗證靜態變數的執行緒安全性: (1)從程式執行的圖中我們可以看出,執行結果中有錯誤資料,證明了靜態變數是存在資源衝突問題的。 (2)程式執行結果圖: ![wKioL1XIYiCz51UGABceSj2NUtI169.bmp](https://img-blog.csdnimg.cn/2021020917241862.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21heHlhbmcxMjEy,size_16,color_FFFFFF,t_70) 5、結論:靜態變數也稱為類變數,屬於類物件所有,位於方法區,為所有物件共享,共享一份記憶體,一旦值被修改,則其他物件均對修改可見,故執行緒非安全。 (二)例項變數:單例時執行緒非安全,非單例時執行緒安全 1、例項變數:例項變數屬於類物件的,也就是說,屬於物件例項私有,在虛擬機器的堆中分配。 2、驗證例項變數的執行緒安全性: (1)從程式截圖中,我們可以看到,當為單例模式時,會產生資源衝突,當非單例模式時,則不會產生執行緒衝突。 (2)程式執行結果圖: 圖1: wKioL1XIYl_RoatmABZU8hrY9Ck087.bmp 圖2: wKioL1XIYpzTOhE2ABZK5iG2N3I856.bmp
3、結論:例項變數是例項物件私有的,系統只存在一個例項物件,則在多執行緒環境下,如果值改變後,則其它物件均可見,故執行緒非安全;如果每個執行緒都在不同的例項物件中執行,
則物件與物件間的修改互不影響,故執行緒安全。
(三)區域性變數:執行緒安全 1、區域性變數:定義在方法內部的變數。 2、驗證區域性變數的安全性: (1)從程式截圖中可以看出,區域性變數在多執行緒下沒有產生資源衝突的問題 (2)程式執行結果圖: wKiom1XIYLvxqpwpABZORsRL6uY028.bmp 3、結論:每個執行緒執行時都會把區域性變數放在各自的幀棧的記憶體空間中,執行緒間不共享,故不存線上程安全問題。 (四)靜態方法的執行緒安全性 1、靜態方法中如果沒有使用靜態變數,則沒有執行緒安全的問題; 靜態方法內的變數,每個執行緒呼叫時,都會新建立一份,不會公用一個儲存單元,故不存線上程衝突的問題。 以上就是對多執行緒環境下靜態變數、例項變數和區域性變數的一點點研究,也僅供自己在需要或遺忘的時候查詢參考下了。