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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

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

轉(zhuǎn)載

?

java多線(xiàn)程編程中,存在很多線(xiàn)程安全問(wèn)題,至于什么是線(xiàn)程安全呢,給出一個(gè)通俗易懂概念還是蠻難,如同《java并發(fā)編程實(shí)踐》中所說(shuō):

寫(xiě)道

?

給線(xiàn)程安全下定義比較困難。存在很多種定義,如:“一個(gè)類(lèi)在可以被多個(gè)線(xiàn)程安全調(diào)用時(shí)就是線(xiàn)程安全”。?

?

?此處不贅述了,首先給出靜態(tài)變量、實(shí)例變量、局部變量在多線(xiàn)程環(huán)境下線(xiàn)程安全問(wèn)題結(jié)論,然后用示例驗(yàn)證,請(qǐng)大家擦亮眼睛,有錯(cuò)必究,否則誤人子弟!

?

?

?

靜態(tài)變量:線(xiàn)程非安全。

?

靜態(tài)變量即類(lèi)變量,位于方法區(qū),為所有對(duì)象共享,共享一份內(nèi)存,一旦靜態(tài)變量被修改,其他對(duì)象均對(duì)修改可見(jiàn),故線(xiàn)程非安全。

?

?

?

實(shí)例變量:單例模式(只有一個(gè)對(duì)象實(shí)例存在)線(xiàn)程非安全,非單例線(xiàn)程安全。

?

實(shí)例變量為對(duì)象實(shí)例私有,在虛擬機(jī)堆中分配,若在系統(tǒng)中只存在一個(gè)此對(duì)象實(shí)例,在多線(xiàn)程環(huán)境下,“猶如”靜態(tài)變量那樣,被某個(gè)線(xiàn)程修改后,其他線(xiàn)程對(duì)修改均可見(jiàn),故線(xiàn)程非安全;如果每個(gè)線(xiàn)程執(zhí)行都是在不同對(duì)象中,那對(duì)象與對(duì)象之間實(shí)例變量修改將互不影響,故線(xiàn)程安全。

?

局部變量:線(xiàn)程安全。

?

每個(gè)線(xiàn)程執(zhí)行時(shí)將會(huì)把局部變量放在各自棧幀工作內(nèi)存中,線(xiàn)程間不共享,故不存在線(xiàn)程安全問(wèn)題。

?

?

?

靜態(tài)變量線(xiàn)程安全問(wèn)題模擬:

?

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

?

?

?

Java代碼??
  • /**??
  • ??*?線(xiàn)程安全問(wèn)題模擬執(zhí)行??
  • ??*??------------------------------??
  • ??*???????線(xiàn)程1??????|????線(xiàn)程2??
  • ??*??------------------------------??
  • ??*???static_i?=?4;??|?等待??
  • ??*???static_i?=?10;?|?等待??
  • ??*????等待??????????|?static_i?=?4;??
  • ??*???static_i?*?2;??|?等待??
  • ??*??-----------------------------?
  • ?*?*/??
  • public?class?Test?implements?Runnable??
  • {??
  • ????private?static?int?static_i;//靜態(tà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();??
  • ????????//啟動(dòng)盡量多線(xiàn)程才能很容易模擬問(wèn)題???
  • ????????for?(int?i?=?0;?i?<?3000;?i++)??
  • ????????{??
  • ????????????//t可以換成new?Test(),保證每個(gè)線(xiàn)程都在不同對(duì)象中執(zhí)行,結(jié)果一樣???
  • ????????????new?Thread(t,?"線(xiàn)程"?+?i).start();??
  • ????????}??
  • ????}??
  • }??
  • ?

    ?

    ?

    ?

    ?

    ?

    ?

    根據(jù)代碼注釋中模擬情況,當(dāng)線(xiàn)程1執(zhí)行了static_i = 4;??static_i = 10; 后,線(xiàn)程2獲得執(zhí)行權(quán),static_i = 4;?然后當(dāng)線(xiàn)程1獲得執(zhí)行權(quán)執(zhí)行static_i * 2;? 必然輸出結(jié)果4*2=8,按照這個(gè)模擬,我們可能會(huì)在控制臺(tái)看到輸出為8結(jié)果。

    ?

    寫(xiě)道

    ?

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

    ?

    ?看紅色標(biāo)注部分,確實(shí)出現(xiàn)了我們預(yù)想,同樣也證明了我們結(jié)論。

    ?

    ?

    ?

    實(shí)例變量線(xiàn)程安全問(wèn)題模擬:

    ?

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

    ?

    Java代碼??
  • public?class?Test?implements?Runnable??
  • {??
  • ????private?int?instance_i;//實(shí)例變量??
  • ??????
  • ????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();??
  • ????????//啟動(dòng)盡量多線(xiàn)程才能很容易模擬問(wèn)題???
  • ????????for?(int?i?=?0;?i?<?3000;?i++)??
  • ????????{??
  • ????????????//每個(gè)線(xiàn)程對(duì)在對(duì)象t中運(yùn)行,模擬單例情況??
  • ????????????new?Thread(t,?"線(xiàn)程"?+?i).start();??
  • ????????}??
  • ????}??
  • }??
  • ?

    ?

    ?

    ?

    ?

    按照本文開(kāi)頭分析,猶如靜態(tài)變量那樣,每個(gè)線(xiàn)程都在修改同一個(gè)對(duì)象實(shí)例變量,肯定會(huì)出現(xiàn)線(xiàn)程安全問(wèn)題。

    ?

    寫(xiě)道

    ?

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

    ?

    ?

    ?

    看紅色字體,可知單例情況下,實(shí)例變量線(xiàn)程非安全。

    ?

    ?

    ?

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

    ?

    ?

    ?

    ?

    ?

    局部變量線(xiàn)程安全問(wèn)題模擬:

    ?

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

    ?

    ?

    ?

    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();??
  • ????????//啟動(dòng)盡量多線(xiàn)程才能很容易模擬問(wèn)題??
  • ????????for?(int?i?=?0;?i?<?3000;?i++)??
  • ????????{??
  • ????????????//每個(gè)線(xiàn)程對(duì)在對(duì)象t中運(yùn)行,模擬單例情況???
  • ????????????new?Thread(t,?"線(xiàn)程"?+?i).start();??
  • ????????}??
  • ????}??
  • }??
  • ?

    ?

    ?

    ?

    ?

    控制臺(tái)沒(méi)有出現(xiàn)異常數(shù)據(jù)。

    ?

    ?

    ?

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

    ?

    以上只是通過(guò)簡(jiǎn)單實(shí)例來(lái)展示靜態(tài)變量、實(shí)例變量、局部變量線(xiàn)程安全問(wèn)題,

    ?

    并未進(jìn)行底層分析,下一篇將對(duì)線(xiàn)程問(wèn)題底層進(jìn)行剖析。

    ?


    ?

    ?

    ?

    靜態(tài)方法是線(xiàn)程安全

    ?

    ?

    ?

    先看一個(gè)類(lèi)

    ?

    public class? Test{

    ?

    public static? String hello(String str){

    ?

    ??? String?tmp="";

    ?

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

    ?

    ?? return?tmp;

    ?

    }

    ?

    }

    ?

    hello方法會(huì)不會(huì)有多線(xiàn)程安全問(wèn)題呢?沒(méi)有!!

    ?

    靜態(tài)方法如果沒(méi)有使用靜態(tài)變量,則沒(méi)有線(xiàn)程安全問(wèn)題。

    ?

    為什么呢?因?yàn)?strong style="color:#000000;background-color:#a0ffff;">靜態(tài)方法內(nèi)聲明變量,每個(gè)線(xiàn)程調(diào)用時(shí),都會(huì)新創(chuàng)建一份,而不會(huì)共用一個(gè)存儲(chǔ)單元。比如這里tmp,每個(gè)線(xiàn)程都會(huì)創(chuàng)建自己一份,因此不會(huì)有線(xiàn)程安全問(wèn)題

    ?

    ?

    ?

    注意,靜態(tài)變量,由于是在類(lèi)加載時(shí)占用一個(gè)存儲(chǔ)區(qū),每個(gè)線(xiàn)程都是共用這個(gè)存儲(chǔ)區(qū),所以如果在靜態(tài)方法里使用了靜態(tài)變量,這就會(huì)有線(xiàn)程安全問(wèn)題!

    總結(jié):只要方法內(nèi)含有靜態(tài)變量,就是非線(xiàn)程安全

    總結(jié)

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

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。