欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Synchronized的原理是什么

本篇內(nèi)容主要講解“Synchronized的原理是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Synchronized的原理是什么”吧!

創(chuàng)新互聯(lián)長(zhǎng)期為上千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為晉州企業(yè)提供專業(yè)的成都網(wǎng)站建設(shè)、成都網(wǎng)站制作,晉州網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

一、對(duì)象鎖、類鎖

當(dāng)synchronized修飾普通方法、修飾某個(gè)對(duì)象、修飾this時(shí),是對(duì)象鎖,只有相同的對(duì)象可以訪問。

當(dāng)synchronized修飾靜態(tài)方法、修飾.class時(shí),是類鎖,同一個(gè)類的不同實(shí)例都可以訪問。

public class Test {

    Object o1=new Object();
    Object o2=new Object();
	
    public synchronized void test1() {
        int i = 5;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException ie) {
            }
        }
    }
    public void test2() {
        synchronized (this){
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                }
            }
        }
    }
    public static synchronized void test3() {
        int i = 5;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException ie) {
            }
        }
    }
    public void test4() {
        synchronized (Test.class){
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                }
            }
        }
    }
    public void test5() {
        synchronized (o1){
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                }
            }
        }
    }
    public void test6() {
        synchronized (o2){
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                }
            }
        }
    }
    public void test7() {
        synchronized (o2){
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                }
            }
        }
    }
    public static void main(String[] args) {
        final Test myt1 = new Test();
		final Test myt2 = new Test();
        Thread test1 = new Thread(new Runnable() {
            @Override
            public void run() {
                myt.test1();
            }
        }, "test1");
        Thread test2 = new Thread(new Runnable() {
            @Override
            public void run() {
                myt.test2();
            }
        }, "test2");
        test1.start();
        test2.start();
    }
}

當(dāng)兩個(gè)線程都使用myt1這個(gè)對(duì)象去訪問方法時(shí):

1,2是同一把鎖(會(huì)產(chǎn)生鎖的競(jìng)爭(zhēng));3,4是同一把鎖;6,7是同一把鎖;他們相互之間是不同的鎖。

當(dāng)兩個(gè)線程分別使用myt1和myt2去訪問方法時(shí):

1,2是不同的鎖(因?yàn)閙yt1和myt2是不同的對(duì)象);3,4是同一把鎖(因?yàn)閙yt1和myt2是相同的類);6,7是不同的鎖。

二、sychronized原理

對(duì)象鎖的實(shí)現(xiàn)使用的是monitorenter 和 monitorexit 指令,其中monitorenter指令指向同步代碼塊的開始位置,monitorexit指令則指明同步代碼塊的結(jié)束位置,當(dāng)執(zhí)行monitorenter指令時(shí),當(dāng)前線程將試圖獲取 objectref(即對(duì)象鎖) 所對(duì)應(yīng)的 monitor 的持有權(quán),當(dāng) objectref 的 monitor 的進(jìn)入計(jì)數(shù)器為 0,那線程可以成功取得 monitor,并將計(jì)數(shù)器值設(shè)置為 1,取鎖成功。如果當(dāng)前線程已經(jīng)擁有 objectref 的 monitor 的持有權(quán),那它可以重入這個(gè) monitor (關(guān)于重入性稍后會(huì)分析),重入時(shí)計(jì)數(shù)器的值也會(huì)加 1。倘若其他線程已經(jīng)擁有 objectref 的 monitor 的所有權(quán),那當(dāng)前線程將被阻塞,直到正在執(zhí)行線程執(zhí)行完畢,即monitorexit指令被執(zhí)行,執(zhí)行線程將釋放 monitor(鎖)并設(shè)置計(jì)數(shù)器值為0 ,其他線程將有機(jī)會(huì)持有 monitor 。

而monitor的本質(zhì)是操作系統(tǒng)的互斥鎖(Mutex Lock)

java中每個(gè)對(duì)象都可以成為鎖,是因?yàn)閖ava對(duì)象頭的設(shè)計(jì):

對(duì)象頭含有三部分:Mark Word(存儲(chǔ)對(duì)象自身運(yùn)行時(shí)數(shù)據(jù))、Class Metadata Address(存儲(chǔ)類元數(shù)據(jù)的指針)、Array length(數(shù)組長(zhǎng)度,只有數(shù)組類型才有)。重點(diǎn)在Mark Word部分,Mark Word數(shù)據(jù)結(jié)構(gòu)被設(shè)計(jì)成非固定的,會(huì)隨著對(duì)象的不同狀態(tài)而變化,如下表所示:

Synchronized的原理是什么

Synchronized的原理是什么

2、拷貝對(duì)象頭中的Mark Word復(fù)制到鎖記錄中;

3、拷貝成功后,虛擬機(jī)將使用CAS操作嘗試將對(duì)象的Mark Word更新為指向Lock Record的指針,并將Lock record里的owner指針指向object mark word。如果更新成功,則執(zhí)行步驟4,否則執(zhí)行步驟5。

4、如果這個(gè)更新動(dòng)作成功了,那么這個(gè)線程就擁有了該對(duì)象的鎖,并且對(duì)象Mark Word的鎖標(biāo)志位設(shè)置為“00”,即表示此對(duì)象處于輕量級(jí)鎖定狀態(tài),這時(shí)候線程堆棧與對(duì)象頭的狀態(tài)如圖所示。

5、如果這個(gè)更新操作失敗了,虛擬機(jī)首先會(huì)檢查對(duì)象的Mark Word是否指向當(dāng)前線程的棧幀,如果是就說明當(dāng)前線程已經(jīng)擁有了這個(gè)對(duì)象的鎖,那就可以直接進(jìn)入同步塊繼續(xù)執(zhí)行。否則說明多個(gè)線程競(jìng)爭(zhēng)鎖,輕量級(jí)鎖就要膨脹為重量級(jí)鎖,鎖標(biāo)志的狀態(tài)值變?yōu)椤?0”,Mark Word中存儲(chǔ)的就是指向重量級(jí)鎖(互斥量)的指針,后面等待鎖的線程也要進(jìn)入阻塞狀態(tài)。 而當(dāng)前線程便嘗試使用自旋來獲取鎖,自旋就是為了不讓線程阻塞,而采用循環(huán)去獲取鎖的過程。

輕量級(jí)鎖釋放:

之前在獲取鎖的時(shí)候它拷貝了鎖對(duì)象頭的markword,在釋放鎖的時(shí)候如果它發(fā)現(xiàn)在它持有鎖的期間有其他線程來嘗試獲取鎖了,并且該線程對(duì)markword做了修改,兩者比對(duì)發(fā)現(xiàn)不一致,則切換到重量鎖。

總結(jié)加鎖流程:

  1. 檢測(cè)Mark Word里面是不是當(dāng)前線程的ID,如果是,表示當(dāng)前線程處于偏向鎖

  2. 如果不是,則使用CAS將當(dāng)前線程的ID替換Mard Word,如果成功則表示當(dāng)前線程獲得偏向鎖,置偏向標(biāo)志位1

  3. 如果失敗,則說明發(fā)生競(jìng)爭(zhēng),撤銷偏向鎖,進(jìn)而升級(jí)為輕量級(jí)鎖。

  4. 當(dāng)前線程使用CAS將對(duì)象頭的Mark Word替換為鎖記錄指針,如果成功,當(dāng)前線程獲得鎖

  5. 如果失敗,表示其他線程競(jìng)爭(zhēng)鎖,當(dāng)前線程便嘗試使用自旋來獲取鎖。

  6. 如果自旋成功則依然處于輕量級(jí)狀態(tài)。

  7. 如果自旋失敗,則升級(jí)為重量級(jí)鎖

https://blog.csdn.net/zqz_zqz/article/details/70233767

https://blog.csdn.net/u012465296/article/details/53022317

https://www.cnblogs.com/javaminer/p/3889023.html

到此,相信大家對(duì)“Synchronized的原理是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

當(dāng)前題目:Synchronized的原理是什么
地址分享:http://chinadenli.net/article6/ipgsog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)網(wǎng)站維護(hù)移動(dòng)網(wǎng)站建設(shè)ChatGPT網(wǎng)站建設(shè)營(yíng)銷型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司