久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

并發(fā)和多線程-八面玲瓏的synchronized

 太極混元天尊 2018-06-11

為什么說(shuō)synchronized是八面玲瓏呢,因?yàn)樗梢曰燠E在很多“場(chǎng)所”(方法,、代碼塊),,與各種角色(類(lèi)、對(duì)象)打交道,。

也正是因?yàn)樗陌嗣媪岘?,所以就顯得比較神秘,也比較復(fù)雜,今天就來(lái)追蹤下synchronized常去的地方和經(jīng)常搭訕的角色,。核心概念主要是介紹對(duì)象鎖和類(lèi)鎖,。

背景

synchronized,作為一種鎖,,主要是用于解決在多線程下的同步問(wèn)題,。

上篇中,我們?cè)诮榻B可見(jiàn)性的時(shí)候提到了java的內(nèi)存模型,,有主內(nèi)存和工作內(nèi)存,。

對(duì)應(yīng)到我們常見(jiàn)的堆、棧的理解是這樣的,。

主內(nèi)存主要包括本地方法區(qū)和堆,。每個(gè)線程都有一個(gè)工作內(nèi)存,,工作內(nèi)存中主要包括兩個(gè)部分,,一個(gè)是屬于該線程私有的棧和對(duì)主存部分變量拷貝的寄存器(包括程序計(jì)數(shù)器PC和cup工作的高速緩存區(qū))。

1.所有的變量都存儲(chǔ)在主內(nèi)存中(虛擬機(jī)內(nèi)存的一部分),,對(duì)于所有線程都是共享的,。

2.每條線程都有自己的工作內(nèi)存,工作內(nèi)存中保存的是主存中某些變量的拷貝,,線程對(duì)變量的所有操作都必須在工作內(nèi)存中進(jìn)行,,而不能直接讀寫(xiě)主內(nèi)存中的變量。

3.線程之間無(wú)法直接訪問(wèn)對(duì)方的工作內(nèi)存中的變量,,線程間變量的傳遞均需要通過(guò)主內(nèi)存來(lái)完成,。

在JVM中,每個(gè)對(duì)象和類(lèi)都會(huì)與一個(gè)監(jiān)聽(tīng)器關(guān)聯(lián),,為了實(shí)現(xiàn)監(jiān)聽(tīng)器的排他監(jiān)視能力,,每個(gè)對(duì)象和類(lèi)都會(huì)關(guān)聯(lián)一個(gè)鎖。當(dāng)某個(gè)線程獲取了某個(gè)對(duì)象的鎖,,則由于排他性,,其他線程就會(huì)阻塞等待獲取鎖以獲取執(zhí)行權(quán)。

每個(gè)對(duì)象都只有唯一一個(gè)鎖,,同一時(shí)間,,也只有一個(gè)線程可以擁有該鎖。

類(lèi)鎖,,其實(shí)可以理解為一種特殊的對(duì)象鎖,,因?yàn)樵贘VM并不存在所謂的類(lèi)鎖。

當(dāng)JVM加載某個(gè)class時(shí),,加在這個(gè)Class對(duì)象上的就是類(lèi)鎖,。所有該類(lèi)的實(shí)例共享這個(gè)類(lèi)鎖,當(dāng)某對(duì)象獲取類(lèi)鎖權(quán)限時(shí),則對(duì)于所有靜態(tài)方法具有相同的執(zhí)行權(quán),。

使用synchronized和未使用synchronized的對(duì)比

1,、 不使用synchronized

并發(fā)和多線程-八面玲瓏的synchronized

并發(fā)和多線程-八面玲瓏的synchronized

并發(fā)和多線程-八面玲瓏的synchronized

并發(fā)和多線程-八面玲瓏的synchronized

  • 該代碼實(shí)例是多線程環(huán)境(兩個(gè)線程)
  • 兩個(gè)線程共用一個(gè)實(shí)例,HasSelfPrivateNum類(lèi)的實(shí)例
  • 在main主線程中分別啟動(dòng)ThreadA和ThreadB
  • 不考慮重排序,,首先創(chuàng)建ThreadA并啟動(dòng),,此時(shí)判斷username.equal('a'),成立,,此時(shí)賦值num=100,,并休眠2秒鐘
  • 在線程A休眠期間,因?yàn)闆](méi)有實(shí)現(xiàn)同步,,所以ThreadB啟動(dòng)也進(jìn)入該方法,,判定username.equal('a')不符合(此時(shí)username='b'),所以此時(shí)num=200
  • 等到ThreadA的2秒睡眠時(shí)間過(guò)去后,,此時(shí)發(fā)現(xiàn)num已經(jīng)被賦值200,,所以此時(shí)也打印出num=200

最后的執(zhí)行結(jié)果如下

并發(fā)和多線程-八面玲瓏的synchronized

注意:

這里有一個(gè)可見(jiàn)性的思考。當(dāng)我們?nèi)绻麤](méi)有接觸或者不了解可見(jiàn)性這個(gè)概念之前,,我們想當(dāng)然的認(rèn)為T(mén)hreadA和ThreadB都是操作了num變量,,那么對(duì)于同一個(gè)變量操作肯定最終都是保持一致的,所以都是num=200,。

其實(shí)這里的num變量是共享變量,,所以會(huì)存在被覆蓋的情況。如果這個(gè)num變量是聲明在addI(String username)方法里面,,那么這時(shí)候鑒于可見(jiàn)性,,雖然都是操作num,但是每個(gè)線程都持有自己的num副本,,所以最后的結(jié)果是這樣的

a set over!

b set over!

b num=200

a num=100

2,、使用synchronized

上面的例子是沒(méi)有使用synchronized的情況,如果加上synchronized關(guān)鍵字,,這時(shí)候相當(dāng)于在addI()方法上加鎖了,,更準(zhǔn)確的說(shuō)是在HasSelfPrivateNum類(lèi)的實(shí)例化對(duì)象上獲取了對(duì)象鎖。

鑒于一個(gè)對(duì)象在同一時(shí)間只能被一個(gè)線程占有,,所以當(dāng)ThreadA進(jìn)入方法后,,會(huì)一直執(zhí)行知道結(jié)束,即使這里有休眠2秒鐘,,ThreadB只能乖乖的等ThreadA執(zhí)行完才能獲取執(zhí)行權(quán)繼續(xù)執(zhí)行,。最終執(zhí)行結(jié)果如下

并發(fā)和多線程-八面玲瓏的synchronized

synchronized使用的四種同步場(chǎng)景

synchronized使用場(chǎng)景主要包括如下四種同步場(chǎng)景

  • 實(shí)例方法(對(duì)象鎖)
  • 靜態(tài)方法(類(lèi)鎖)
  • 實(shí)例方法中的代碼塊(對(duì)象鎖)
  • 靜態(tài)方法中的代碼塊(類(lèi)鎖)

1、實(shí)例方法

參見(jiàn)上面對(duì)比例子中“加synchronized”的情況

2,、靜態(tài)方法

并發(fā)和多線程-八面玲瓏的synchronized

并發(fā)和多線程-八面玲瓏的synchronized

并發(fā)和多線程-八面玲瓏的synchronized

執(zhí)行結(jié)果如下

線程名稱為:A在1528626219469進(jìn)入printA

線程名稱為:A在1528626222473離開(kāi)printA

線程名稱為:B在1528626222473進(jìn)入printB

線程名稱為:B在1528626222474離開(kāi)printB

這里的synchronized是加載靜態(tài)方法上的,,我們知道靜態(tài)方法是通過(guò)類(lèi)直接調(diào)用的,,不需要實(shí)例化的。這里用的就是類(lèi)鎖,,也就是類(lèi)的Class對(duì)象的鎖,,所以這里兩個(gè)線程在同一時(shí)間也只會(huì)有一個(gè)獲取到該類(lèi)鎖從而獲得執(zhí)行權(quán)。

3,、實(shí)例方法中的同步塊

直接看代碼

并發(fā)和多線程-八面玲瓏的synchronized

并發(fā)和多線程-八面玲瓏的synchronized

并發(fā)和多線程-八面玲瓏的synchronized

執(zhí)行結(jié)果如下

begin time=1528625980467

end end=1528625982471

begin time=1528625982471

end end=1528625984472

這里的this就是ObjectService類(lèi)的實(shí)例化對(duì)象,,因?yàn)橐粋€(gè)對(duì)象只有一個(gè)對(duì)象鎖,所以這里可以保證同步,,只有前一個(gè)線程執(zhí)行完后,,后一個(gè)線程才有機(jī)會(huì)執(zhí)行。

4,、靜態(tài)方法中的同步塊

參見(jiàn)2和3,,只是在靜態(tài)方法內(nèi)部加上synchronized。本質(zhì)還是類(lèi)鎖,。

文中肯定有理解偏差的地方,,寫(xiě)博客的好處就是,本來(lái)已經(jīng)認(rèn)為理所當(dāng)然的地方,,當(dāng)需要一字一句寫(xiě)出來(lái)的時(shí)候,,就會(huì)加深思考一些問(wèn)題的細(xì)節(jié),。

好比文中沒(méi)有加synchronized的例子,,突然想到可見(jiàn)性,又想到主內(nèi)存和工作內(nèi)存以及堆棧之類(lèi)的內(nèi)存結(jié)構(gòu),,雖然一度被繞暈,,查了兩小時(shí)的資料,最終也算是找了一套理論勉強(qiáng)把自己說(shuō)服,。

如果您覺(jué)得閱讀本文對(duì)您有幫助,,請(qǐng)點(diǎn)一下“關(guān)注”按鈕,您的“關(guān)注”將是我最大的寫(xiě)作動(dòng)力,!

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多