日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java线程安全问题之静态变量、实例变量、局部变量

發布時間:2024/4/14 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java线程安全问题之静态变量、实例变量、局部变量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載

?

java多線程編程中,存在很多線程安全問題,至于什么是線程安全呢,給出一個通俗易懂概念還是蠻難,如同《java并發編程實踐》中所說:

寫道

?

給線程安全下定義比較困難。存在很多種定義,如:“一個在可以被多個線程安全調用時就是線程安全”。?

?

?此處不贅述了,首先給出靜態變量、實例變量、局部變量在多線程環境下線程安全問題結論,然后用示例驗證,請大家擦亮眼睛,有錯必究,否則誤人子弟!

?

?

?

靜態變量:線程非安全。

?

靜態變量即變量,位于方法區,為所有對象共享,共享一份內存,一旦靜態變量被修改,其他對象均對修改可見,故線程非安全。

?

?

?

實例變量:單例模式(只有一個對象實例存在)線程非安全,非單例線程安全。

?

實例變量為對象實例私有,在虛擬機堆中分配,若在系統中只存在一個此對象實例,在多線程環境下,“猶如”靜態變量那樣,被某個線程修改后,其他線程對修改均可見,故線程非安全;如果每個線程執行都是在不同對象中,那對象與對象之間實例變量修改將互不影響,故線程安全。

?

局部變量:線程安全。

?

每個線程執行時將會把局部變量放在各自棧幀工作內存中,線程間不共享,故不存在線程安全問題。

?

?

?

靜態變量線程安全問題模擬:

?

----------------------------------------------------------------------------------

?

?

?

Java代碼??
  • /**??
  • ??*?線程安全問題模擬執行??
  • ??*??------------------------------??
  • ??*???????線程1??????|????線程2??
  • ??*??------------------------------??
  • ??*???static_i?=?4;??|?等待??
  • ??*???static_i?=?10;?|?等待??
  • ??*????等待??????????|?static_i?=?4;??
  • ??*???static_i?*?2;??|?等待??
  • ??*??-----------------------------?
  • ?*?*/??
  • public?class?Test?implements?Runnable??
  • {??
  • ????private?static?int?static_i;//靜態變量???
  • ??????
  • ????public?void?run()??
  • ????{??
  • ????????static_i?=?4;??
  • ????????System.out.println("["?+?Thread.currentThread().getName()??
  • ????????????????+?"]獲取static_i?值:"?+?static_i);??
  • ????????static_i?=?10;??
  • ????????System.out.println("["?+?Thread.currentThread().getName()??
  • ????????????????+?"]獲取static_i*3值:"?+?static_i?*?2);??
  • ????}??
  • ??????
  • ????public?static?void?main(String[]?args)??
  • ????{??
  • ????????Test?t?=?new?Test();??
  • ????????//啟動盡量多線程才能很容易模擬問題???
  • ????????for?(int?i?=?0;?i?<?3000;?i++)??
  • ????????{??
  • ????????????//t可以換成new?Test(),保證每個線程都在不同對象中執行,結果一樣???
  • ????????????new?Thread(t,?"線程"?+?i).start();??
  • ????????}??
  • ????}??
  • }??
  • ?

    ?

    ?

    ?

    ?

    ?

    ?

    根據代碼注釋中模擬情況,當線程1執行了static_i = 4;??static_i = 10; 后,線程2獲得執行權,static_i = 4;?然后當線程1獲得執行權執行static_i * 2;? 必然輸出結果4*2=8,按照這個模擬,我們可能會在控制臺看到輸出為8結果。

    ?

    寫道

    ?

    [線程27]獲取static_i 值:4?
    [線程22]獲取static_i*2值:20?
    [線程28]獲取static_i 值:4?
    [線程23]獲取static_i*2值:8?
    [線程29]獲取static_i 值:4?
    [線程30]獲取static_i 值:4?
    [線程31]獲取static_i 值:4?
    [線程24]獲取static_i*2值:20

    ?

    ?看紅色標注部分,確實出現了我們預想,同樣也證明了我們結論。

    ?

    ?

    ?

    實例變量線程安全問題模擬:

    ?

    ----------------------------------------------------------------------------------

    ?

    Java代碼??
  • public?class?Test?implements?Runnable??
  • {??
  • ????private?int?instance_i;//實例變量??
  • ??????
  • ????public?void?run()??
  • ????{??
  • ????????instance_i?=?4;??
  • ????????System.out.println("["?+?Thread.currentThread().getName()??
  • ????????????????+?"]獲取instance_i?值:"?+?instance_i);??
  • ????????instance_i?=?10;??
  • ????????System.out.println("["?+?Thread.currentThread().getName()??
  • ????????????????+?"]獲取instance_i*3值:"?+?instance_i?*?2);??
  • ????}??
  • ??????
  • ????public?static?void?main(String[]?args)??
  • ????{??
  • ????????Test?t?=?new?Test();??
  • ????????//啟動盡量多線程才能很容易模擬問題???
  • ????????for?(int?i?=?0;?i?<?3000;?i++)??
  • ????????{??
  • ????????????//每個線程對在對象t中運行,模擬單例情況??
  • ????????????new?Thread(t,?"線程"?+?i).start();??
  • ????????}??
  • ????}??
  • }??
  • ?

    ?

    ?

    ?

    ?

    按照本文開頭分析,猶如靜態變量那樣,每個線程都在修改同一個對象實例變量,肯定會出現線程安全問題。

    ?

    寫道

    ?

    [線程66]獲取instance_i 值:10?
    [線程33]獲取instance_i*2值:20?
    [線程67]獲取instance_i 值:4?
    [線程34]獲取instance_i*2值:8?
    [線程35]獲取instance_i*2值:20?
    [線程68]獲取instance_i 值:4

    ?

    ?

    ?

    看紅色字體,可知單例情況下,實例變量線程非安全。

    ?

    ?

    ?

    將new Thread(t, "線程" + i).start();改成new Thread(new Test(), "線程" + i).start();模擬非單例情況,會發現不存在線程安全問題。

    ?

    ?

    ?

    ?

    ?

    局部變量線程安全問題模擬:

    ?

    ----------------------------------------------------------------------------------

    ?

    ?

    ?

    Java代碼??
  • public?class?Test?implements?Runnable??
  • {??
  • ????public?void?run()??
  • ????{??
  • ????????int?local_i?=?4;??
  • ????????System.out.println("["?+?Thread.currentThread().getName()??
  • ????????????????+?"]獲取local_i?值:"?+?local_i);??
  • ????????local_i?=?10;??
  • ????????System.out.println("["?+?Thread.currentThread().getName()??
  • ????????????????+?"]獲取local_i*2值:"?+?local_i?*?2);??
  • ????}??
  • ??????
  • ????public?static?void?main(String[]?args)??
  • ????{??
  • ????????Test?t?=?new?Test();??
  • ????????//啟動盡量多線程才能很容易模擬問題??
  • ????????for?(int?i?=?0;?i?<?3000;?i++)??
  • ????????{??
  • ????????????//每個線程對在對象t中運行,模擬單例情況???
  • ????????????new?Thread(t,?"線程"?+?i).start();??
  • ????????}??
  • ????}??
  • }??
  • ?

    ?

    ?

    ?

    ?

    控制臺沒有出現異常數據。

    ?

    ?

    ?

    ---------------------------------------------------------------

    ?

    以上只是通過簡單實例來展示靜態變量、實例變量、局部變量線程安全問題,

    ?

    并未進行底層分析,下一篇將對線程問題底層進行剖析。

    ?


    ?

    ?

    ?

    靜態方法是線程安全

    ?

    ?

    ?

    先看一個

    ?

    public class? Test{

    ?

    public static? String hello(String str){

    ?

    ??? String?tmp="";

    ?

    ????tmp? =??tmp+str;

    ?

    ?? return?tmp;

    ?

    }

    ?

    }

    ?

    hello方法會不會有多線程安全問題呢?沒有!!

    ?

    靜態方法如果沒有使用靜態變量,則沒有線程安全問題。

    ?

    為什么呢?因為靜態方法內聲明變量,每個線程調用時,都會新創建一份,而不會共用一個存儲單元。比如這里tmp,每個線程都會創建自己一份,因此不會有線程安全問題

    ?

    ?

    ?

    注意,靜態變量,由于是在加載時占用一個存儲區,每個線程都是共用這個存儲區,所以如果在靜態方法里使用了靜態變量,這就會有線程安全問題!

    總結:只要方法內含有靜態變量,就是非線程安全

    總結

    以上是生活随笔為你收集整理的java线程安全问题之静态变量、实例变量、局部变量的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。