最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java多線程編程中易混淆的3個(gè)關(guān)鍵字總結(jié)

 更新時(shí)間:2015年03月23日 09:22:18   投稿:junjie  
這篇文章主要介紹了Java多線程編程中易混淆的3個(gè)關(guān)鍵字總結(jié),本文總結(jié)了、volatile、ThreadLocal、synchronized等3個(gè)關(guān)鍵字,對(duì)這幾個(gè)容易混淆概念的關(guān)鍵字分別做了講解,需要的朋友可以參考下

概述

最近在看《ThinKing In Java》,看到多線程章節(jié)時(shí)覺得有一些概念比較容易混淆有必要總結(jié)一下,雖然都不是新的東西,不過還是蠻重要,很基本的,在開發(fā)或閱讀源碼中經(jīng)常會(huì)遇到,在這里就簡(jiǎn)單的做個(gè)總結(jié)。

1.volatile

volatile主要是用來在多線程中同步變量。
在一般情況下,為了提升性能,每個(gè)線程在運(yùn)行時(shí)都會(huì)將主內(nèi)存中的變量保存一份在自己的內(nèi)存中作為變量副本,但是這樣就很容易出現(xiàn)多個(gè)線程中保存的副本變量不一致,或與主內(nèi)存的中的變量值不一致的情況。
而當(dāng)一個(gè)變量被volatile修飾后,該變量就不能被緩存到線程的內(nèi)存中,它會(huì)告訴編譯器不要進(jìn)行任何移出讀取和寫入操作的優(yōu)化,換句話說就是不允許有不同于“主”內(nèi)存區(qū)域的變量拷貝,所以當(dāng)該變量有變化時(shí),所有調(diào)用該變量的線程都會(huì)獲得相同的值,這就確保了該變量在應(yīng)用中的可視性(當(dāng)一個(gè)任務(wù)做出了修改在應(yīng)用中必須是可視的),同時(shí)性能也相應(yīng)的降低了(還是比synchronized高)。
但需要注意volatile只能確保操作的是同一塊內(nèi)存,并不能保證操作的原子性。所以volatile一般用于聲明簡(jiǎn)單類型變量,使得這些變量具有原子性,即一些簡(jiǎn)單的賦值與返回操作將被確保不中斷。但是當(dāng)該變量的值由自身的上一個(gè)決定時(shí),volatile的作用就將失效,這是由volatile關(guān)鍵字的性質(zhì)所決定的。
所以在volatile時(shí)一定要謹(jǐn)慎,千萬不要以為用volatile修飾后該變量的所有操作都是原子操作,不再需要synchronized關(guān)鍵字了。

2.ThreadLocal

首先ThreadLocal和本地線程沒有一毛錢關(guān)系,更不是一個(gè)特殊的Thread,它只是一個(gè)線程的局部變量(其實(shí)就是一個(gè)Map),ThreadLocal會(huì)為每個(gè)使用該變量的線程提供獨(dú)立的變量副本,所以每一個(gè)線程都可以獨(dú)立地改變自己的副本,而不會(huì)影響其它線程所對(duì)應(yīng)的副本。這樣做其實(shí)就是以空間換時(shí)間的方式(與synchronized相反),以耗費(fèi)內(nèi)存為代價(jià),單大大減少了線程同步(如synchronized)所帶來性能消耗以及減少了線程并發(fā)控制的復(fù)雜度。
個(gè)人覺得比較典型的例子就是在Android關(guān)于Looper的源碼中對(duì)ThreadLocal的使用,同時(shí)也包含了ThreadLocal的基本用法,具體代碼如下:

public class Looper { 
private static final String TAG = "Looper";

// sThreadLocal.get() will return null unless you've called prepare(). 
private static final ThreadLocal sThreadLocal = new ThreadLocal(); 

...... 

private static Looper mMainLooper = null; 

...... 

public static final void prepare() { 
  if (sThreadLocal.get() != null) { 
    throw new RuntimeException("Only one Looper may be created per thread"); 
  } 
  sThreadLocal.set(new Looper()); 
} 

...... 

public static final void prepareMainLooper() { 
  prepare(); 
  setMainLooper(myLooper()); 

  ...... 

} 

private synchronized static void setMainLooper(Looper looper) { 
  mMainLooper = looper; 
} 
public synchronized static final Looper getMainLooper() { 
  return mMainLooper; 
} 

...... 

public static final Looper myLooper() { 
  return (Looper)sThreadLocal.get(); 
} 

...... 

} 


但需要注意的是,雖然ThreadLocal和Synchonized都用于解決多線程并發(fā)訪問,ThreadLocal與synchronized還是有本質(zhì)的區(qū)別。synchronized是利用鎖的機(jī)制,使變量或代碼塊在某一時(shí)該只能被一個(gè)線程訪問。而ThreadLocal為每一個(gè)線程都提供了變量的副本,使得每個(gè)線程在某一時(shí)間訪問到的并不是同一個(gè)對(duì)象,這樣就隔離了多個(gè)線程對(duì)數(shù)據(jù)的數(shù)據(jù)共享。而Synchronized卻正好相反,它用于在多個(gè)線程間通信時(shí)能夠獲得數(shù)據(jù)共享。即Synchronized用于線程間的數(shù)據(jù)共享,而ThreadLocal則用于線程間的數(shù)據(jù)隔離。所以ThreadLocal并不能代替synchronized,Synchronized的功能范圍更廣(同步機(jī)制)。

3.synchronized

synchronized關(guān)鍵字是Java利用鎖的機(jī)制自動(dòng)實(shí)現(xiàn)的,一般有同步方法和同步代碼塊兩種使用方式。Java中所有的對(duì)象都自動(dòng)含有單一的鎖(也稱為監(jiān)視器),當(dāng)在對(duì)象上調(diào)用其任意的synchronized方法時(shí),此對(duì)象被加鎖(一個(gè)任務(wù)可以多次獲得對(duì)象的鎖,計(jì)數(shù)會(huì)遞增),同時(shí)在線程從該方法返回之前,該對(duì)象內(nèi)其他所有要調(diào)用類中被標(biāo)記為synchronized的方法的線程都會(huì)被阻塞。當(dāng)然針對(duì)每個(gè)類也有一個(gè)鎖(作為類的Class對(duì)象的一部分),所以你懂的^.^。
最后需要注意的是synchronized是同步機(jī)制中最安全的一種方式,其他的任何方式都是有風(fēng)險(xiǎn)的,當(dāng)然付出的代價(jià)也是最大的。

相關(guān)文章

  • Java解釋器的運(yùn)行過程介紹

    Java解釋器的運(yùn)行過程介紹

    今天小編就為大家分享一篇關(guān)于Java解釋器的運(yùn)行過程介紹,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • 解決springboot bean中大寫的字段返回變成小寫的問題

    解決springboot bean中大寫的字段返回變成小寫的問題

    這篇文章主要介紹了解決springboot bean中大寫的字段返回變成小寫的問題,具有很好的參考價(jià)值希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • MyBatis通過BATCH批量提交的方法

    MyBatis通過BATCH批量提交的方法

    今天小編就為大家分享一篇關(guān)于MyBatis通過BATCH批量提交的方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Java中g(shù)etSuperclass()方法的使用與原理解讀

    Java中g(shù)etSuperclass()方法的使用與原理解讀

    文章介紹了Java中的getSuperclass()方法,該方法用于獲取一個(gè)類的直接父類,通過理解其使用方式、工作原理以及實(shí)際應(yīng)用場(chǎng)景,可以更好地利用反射機(jī)制處理類的繼承關(guān)系,實(shí)現(xiàn)動(dòng)態(tài)類型檢查、類加載以及序列化等功能
    2025-01-01
  • SpringBoot使用Spark過程詳解

    SpringBoot使用Spark過程詳解

    這篇文章主要介紹SpringBoot使用Spark的方法的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望能幫助大家解決問題
    2023-02-02
  • java使用定時(shí)器實(shí)現(xiàn)監(jiān)聽數(shù)據(jù)變化

    java使用定時(shí)器實(shí)現(xiàn)監(jiān)聽數(shù)據(jù)變化

    這篇文章主要為大家詳細(xì)介紹了Java如何使用定時(shí)器監(jiān)聽數(shù)據(jù)變化,當(dāng)滿足某個(gè)條件時(shí)(例如沒有數(shù)據(jù)更新)自動(dòng)執(zhí)行某項(xiàng)任務(wù),有興趣的可以了解下
    2023-11-11
  • Java橋梁設(shè)計(jì)模式優(yōu)雅地將抽象與實(shí)現(xiàn)分離

    Java橋梁設(shè)計(jì)模式優(yōu)雅地將抽象與實(shí)現(xiàn)分離

    Java橋接設(shè)計(jì)模式通過將抽象和實(shí)現(xiàn)分離,使得它們可以獨(dú)立地變化,從而實(shí)現(xiàn)更靈活的代碼結(jié)構(gòu)。它是一種優(yōu)雅的設(shè)計(jì)模式,適用于需要處理多個(gè)變化因素的復(fù)雜應(yīng)用程序
    2023-04-04
  • 解決Java處理HTTP請(qǐng)求超時(shí)的問題

    解決Java處理HTTP請(qǐng)求超時(shí)的問題

    這篇文章主要介紹了解決Java處理HTTP請(qǐng)求超時(shí)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Java 進(jìn)行時(shí)間處理的步驟

    Java 進(jìn)行時(shí)間處理的步驟

    時(shí)間處理是常見的需求,本文將講述Java語言如何進(jìn)行時(shí)間處理,感興趣的朋友可以了解下
    2021-05-05
  • 通過FeignClient如何獲取文件流steam?is?close問題

    通過FeignClient如何獲取文件流steam?is?close問題

    這篇文章主要介紹了通過FeignClient如何獲取文件流steam?is?close問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06

最新評(píng)論

慈利县| 荆门市| 大理市| 洞头县| 永康市| 鲁甸县| 新蔡县| 新平| 康平县| 河北省| 体育| 呈贡县| 松滋市| 砚山县| 铜山县| 广安市| 宁波市| 霍林郭勒市| 时尚| 鹤壁市| 奎屯市| 察隅县| 彩票| 嘉鱼县| 马公市| 特克斯县| 和静县| 长武县| 南丹县| 舟曲县| 蛟河市| 清流县| 略阳县| 阿图什市| 祁东县| 青铜峡市| 庄浪县| 嘉定区| 陆良县| 舞阳县| 娱乐|