轉:https://blog.csdn.net/yy304935305/article/details/52456771php
魯迅先生曾說過:「時間就像海綿裏的水,只要願擠,總仍是有的」。無論腫(怎)麼說,這事仍是要作的啊。若是越日後推,可能形成的潛在影響更大。這始終是個隱患,不能不除。html
不是痛定思痛,而是認識到事情的重要性,就要開始行動了... ...java
以上是我的的閒言碎語,不足而看。下面,咱們就少言幾句進入到技術領域吧!編程
線程,是咱們項目中繞不過的重點領域。提到線程,就常會聽到線程安全的術語。那什麼是線程安全呢?通俗點說,就是線程訪問時不產生資源衝突。其實,這是一個有點難以定義的概念,不是很容易讓人一聽就懂的概念。「一個類能夠被多個線程安全調用就是線程安全的」《java編程併發實踐》。安全
來講說靜態變量、實例變量、局部變量在多線程下的安全問題吧!多線程
(一)靜態變量:線程非安全併發
一、靜態變量:使用static關鍵字定義的變量。static能夠修飾變量和方法,也有static靜態代碼塊。被static修飾的成員變量和成員方法獨立於該類的任何對象。也就是說,它不依賴類特定的實例,被類的全部實例共享。只要這個類被加載,Java虛擬機就能根據類名在運行時數據區的方法區內定找到他們。所以,static對象能夠在它的任何對象建立以前訪問,無需引用任何對象。app
用public修飾的static成員變量和成員方法本質是全局變量和全局方法,當聲明它的類的對象時,不生成static變量的副本,而是類的全部實例共享同一個static變量。ui
二、靜態變量使用的場景:this
(1)對象間共享值時
(2)方便訪問變量時
三、靜態方法使用注意事項:
(1)不能在靜態方法內使用非靜態變量,即不能直接訪問所屬類的實例變量;
(2)不能在靜態方法內直接調用非靜態方法;
(3)靜態方法中不能使用this和super關鍵字;
四、驗證靜態變量的線程安全性:
(1)從程序執行的圖中咱們能夠看出,執行結果中有錯誤數據,證實了靜態變量是存在資源衝突問題的。
(2)程序運行結果圖:
五、結論:靜態變量也稱爲類變量,屬於類對象全部,位於方法區,爲全部對象共享,共享一分內存,一旦值被修改,則其餘對象均對修改可見,故線程非安全。
(二)實例變量:單例時線程非安全,非單例時線程安全
一、實例變量:實例變量屬於類對象的,也就是說,屬於對象實例私有,在虛擬機的堆中分配。
二、驗證明例變量的線程安全性:
(1)從程序截圖中,咱們能夠看到,當爲單例模式時,會產生資源衝突,當非單例模式時,則不會產生線程衝突。
(2)程序運行結果圖:
圖1:
圖2:
三、結論:實例變量是實例對象私有的,系統只存在一個實例對象,則在多線程環境下,若是值改變後,則其它對象都可見,故線程非安全;若是每一個線程都在不一樣的實例對象中執行,
則對象與對象間的修改互不影響,故線程安全。
(三)局部變量:線程安全
一、局部變量:定義在方法內部的變量。
二、驗證局部變量的安全性:
(1)從程序截圖中能夠看出,局部變量在多線程下沒有產生資源衝突的問題
(2)程序運行結果圖:
三、結論:每一個線程執行時都會把局部變量放在各自的幀棧的內存空間中,線程間不共享,故不存在線程安全問題。
(四)靜態方法的線程安全性
一、靜態方法中若是沒有使用靜態變量,則沒有線程安全的問題;
靜態方法內的變量,每一個線程調用時,都會新建立一份,不會公用一個存儲單元,故不存在線程衝突的問題。
以上就是對多線程環境下靜態變量、實例變量和局部變量的一點點研究,也僅供本身在須要或遺忘的時候查詢參考下了。