回覆列表
  • 1 # 農非農

    這個問題的答案是靜態變數和全域性變數都可能引起執行緒安全問題。這兩種變數引起執行緒安全問題的原因和區別如下:

    1、靜態變數

    靜態變數即靜態成員變數。只要有修改變數值的操作,無論是在單例或者非單例都是執行緒不安全的;而如果執行緒只是讀取變數的值,而不會改變變數的值,這種情況下則是執行緒是安全的。

    產生執行緒安全問題的原因:靜態變數即類變數,只初始化一次,位於方法區,為所有物件共享,共享一份記憶體,一旦靜態變數被修改,其他物件均對修改可見,故執行緒非安全。

    靜態變數多執行緒操作示例:

    根據上圖程式碼可知,當執行緒1執行了number = 1; number = 2; 後,執行緒2獲得執行權,number = 1;然後當執行緒1獲得執行權執行列印第二次獲取number時; 必然輸出結果“獲取第二次number = 1”,按照這個模擬,我們可能會在控制檯看到輸出為“獲取第二次number = 1”的結果。如下圖方框中的資料:

    上圖結果顯示了靜態變數執行緒不安全問題。

    2、全域性變數

    全域性變數即例項成員變數。如果執行緒只是讀取變數的值,而不會改變變數的值,則無論是單例還是非單例都是執行緒安全的;如果有修改變數值的操作,則單例模式因為只有一個物件例項singleton存在,多執行緒同時操作時是不安全的,而非單例模式下多執行緒操作是安全的。

    例項變數為物件例項私有,在虛擬機器的堆heap中分配,若在系統中只存在一個此物件的例項,在多執行緒環境下,“猶如”靜態變數那樣,被某個執行緒修改後,其他執行緒對修改均可見,故執行緒非安全(如,springmvc controller是單例的,非執行緒安全的);如果每個執行緒執行都是在不同的物件中,那物件與物件之間的例項變數的修改將互不影響,故執行緒安全(如,struts2 action預設是非單例的,每次請求在heap中new新的action例項,故struts2 action可以用例項成員變數)。

    全域性變數多執行緒操作示例:

    多執行緒操作同一個物件的全域性變數,結果如下圖:

    上圖結果顯示了全域性變數執行緒不安全問題。

  • 2 # java攻城獅

    哈哈,一看這個問題,你應該是個小白。全域性變數和靜態變數都有執行緒安全問題,因為它們都在堆記憶體裡面,被所有執行緒共享。想搞明白多謝執行緒,你先去了解一下java記憶體模型吧。不然說了你也不懂

  • 3 # 網際網路上的追跡者

    你應該是指的應該是共享變數,如果是區域性變數,你執行緒內在區域性原因怎麼用就怎麼用,不會出現競爭條件,自然不會出現安全問題。建議瞭解下jmm

  • 中秋節和大豐收的關聯?
  • 花與劍和尚帶什麼夥伴?