欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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主要是用來(lái)在多線程中同步變量。
在一般情況下,為了提升性能,每個(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)化,換句話說(shuō)就是不允許有不同于“主”內(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)慎,千萬(wà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)所帶來(lái)性能消耗以及減少了線程并發(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 web自定義filter代碼實(shí)例

    Java web自定義filter代碼實(shí)例

    這篇文章主要介紹了Java web自定義filter代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Spring Boot集成springfox-swagger2構(gòu)建restful API的方法教程

    Spring Boot集成springfox-swagger2構(gòu)建restful API的方法教程

    這篇文章主要給大家介紹了關(guān)于Spring Boot集成springfox-swagger2構(gòu)建restful API的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。
    2017-06-06
  • Java高級(jí)特性基礎(chǔ)之反射五連問

    Java高級(jí)特性基礎(chǔ)之反射五連問

    反射賦予了我們?cè)谶\(yùn)行時(shí)分析類以及執(zhí)行類中方法的能力。通過反射你可以獲取任意一個(gè)類的所有屬性和方法,你還可以調(diào)用這些方法和屬性。本文就來(lái)和大家詳細(xì)聊聊Java中的反射,感興趣的可以了解一下
    2023-01-01
  • druid配置數(shù)據(jù)庫(kù)連接使用密文密碼方式

    druid配置數(shù)據(jù)庫(kù)連接使用密文密碼方式

    這篇文章主要介紹了druid配置數(shù)據(jù)庫(kù)連接使用密文密碼方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,
    2023-12-12
  • SpringCloud+Redis實(shí)現(xiàn)Api接口限流防止惡意刷接口

    SpringCloud+Redis實(shí)現(xiàn)Api接口限流防止惡意刷接口

    接口限流是為了保護(hù)系統(tǒng)和服務(wù),防止因?yàn)檫^多的請(qǐng)求而崩潰,本文主要介紹了SpringCloud+Redis實(shí)現(xiàn)Api接口限流防止惡意刷接口,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • 詳解Java設(shè)計(jì)模式中的裝飾模式

    詳解Java設(shè)計(jì)模式中的裝飾模式

    裝飾模式是指在不改變現(xiàn)有對(duì)象結(jié)構(gòu)的情況下,動(dòng)態(tài)地給該對(duì)象增加一些職責(zé)(即增加其額外功能)的模式,它屬于對(duì)象結(jié)構(gòu)型模式。本文將為大家詳細(xì)介紹一下裝飾模式,感興趣的可以了解一下
    2021-12-12
  • Java多線程編程中線程鎖與讀寫鎖的使用示例

    Java多線程編程中線程鎖與讀寫鎖的使用示例

    這篇文章主要介紹了Java多線程編程中線程鎖與讀寫鎖的使用示例,鎖是控制程序多線程并發(fā)的重要手段,需要的朋友可以參考下
    2016-04-04
  • Java集合案例之斗地主游戲

    Java集合案例之斗地主游戲

    這篇文章主要為大家詳細(xì)介紹了Java集合案例之斗地主游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • SpringBoot集成Mybatis-plus并實(shí)現(xiàn)自動(dòng)生成相關(guān)文件的示例代碼

    SpringBoot集成Mybatis-plus并實(shí)現(xiàn)自動(dòng)生成相關(guān)文件的示例代碼

    Mybatis-Plus是一個(gè)優(yōu)秀的Mybatis增強(qiáng)工具,目前更新到3.1.1,本文通過示例代碼給大家介紹SpringBoot集成Mybatis-plus并實(shí)現(xiàn)自動(dòng)生成相關(guān)文件的問題,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • IDEA插件之快速刪除Java代碼中的注釋

    IDEA插件之快速刪除Java代碼中的注釋

    這篇文章主要介紹了IDEA插件之快速刪除Java代碼中的注釋,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02

最新評(píng)論