亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

synchronized鎖了什么

fish / 2144人閱讀

摘要:也有人稱其為同步鎖。既然是鎖,其必然有鎖的東西,下面先會(huì)簡(jiǎn)單介紹一下,再通過(guò)一個(gè)示例代碼展示鎖了什么。從而可以證明并不是鎖定方法內(nèi)訪問(wèn)的變量鎖定的是同一個(gè)監(jiān)視器對(duì)象監(jiān)視的代碼

前言

synchronized翻譯為中文的意思是同步的,它是Java中處理線程安全問(wèn)題常用的關(guān)鍵字。也有人稱其為同步鎖。既然是鎖,其必然有鎖的東西,下面先會(huì)簡(jiǎn)單介紹一下synchronized,再通過(guò)一個(gè)示例代碼展示synchronized鎖了什么。(這里先提前透露答案synchronized鎖的是代碼)

介紹 定義

synchronized提供的同步機(jī)制確保了同一個(gè)時(shí)刻,被修飾的代碼塊或方法只會(huì)有一個(gè)線程執(zhí)行。

用法

synchronized可以修飾方法和代碼塊:

修飾普通方法

修飾靜態(tài)方法

修飾代碼塊

根據(jù)修飾情況,分為對(duì)象鎖和類鎖:

對(duì)象鎖:

普通方法(等價(jià)于代碼塊修飾this

代碼塊修飾的是是類的一個(gè)對(duì)象

類鎖

類方法(等價(jià)于代碼塊修飾當(dāng)前類Class對(duì)象)

代碼塊修飾的是是類Class對(duì)象

原理

synchronized底層原理是使用了對(duì)象持有的監(jiān)視器monitor)。但是同步代碼塊和同步方法的原理存在一點(diǎn)差異:

同步代碼塊是使用monitorentermonitorexit指令實(shí)現(xiàn)的

同步方法是由方法調(diào)用指令讀取運(yùn)行時(shí)常量池中方法的ACC_SYNCHRONIZED 標(biāo)識(shí)隱式實(shí)現(xiàn),實(shí)際上還是調(diào)用了monitorentermonitorexit指令

測(cè)試示例 計(jì)數(shù)器

一個(gè)特殊的計(jì)數(shù)器,自增方法increase()synchronized修飾,而獲取當(dāng)前值方法getCurrent()則沒(méi)有被synchronized修飾。

/**
 * 計(jì)數(shù)器
 * @author RJH
 * create at 2019-03-13
 */
public class Counter {
    /**
     * 全局對(duì)象,總數(shù)
     */
    private static int i = 0;

    /**
     * 自增
     * @return
     */
    public synchronized int increase() {
        try {
            //使用休眠讓結(jié)果更明顯
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ++i;
    }

    /**
     * 獲取當(dāng)前值
     * @return
     */
    public int getCurrent() {
        return i;
    }
}
測(cè)試代碼

使用自增線程和獲取當(dāng)前值的線程來(lái)驗(yàn)證synchronized鎖的是代碼,而不是全局變量

/**
 * synchronized鎖了什么
 * @author RJH
 * create at 2019-03-02
 */
public class LockWhatTest {

    public static void main(String[] args) {
        Counter counter =new Counter();
        IncreaseThread increaseThread1=new IncreaseThread(counter);
        IncreaseThread increaseThread2=new IncreaseThread(counter);
        GetThread getThread=new GetThread(counter);
        increaseThread1.start();
        increaseThread2.start();
        //直到increaseThread的線程啟動(dòng)才執(zhí)行下一步
        while (increaseThread1.getState().compareTo(Thread.State.NEW)==0 && increaseThread1.getState().compareTo(Thread.State.NEW)==0){

        }
        getThread.start();
    }

    /**
     * 自增線程
     */
    static class IncreaseThread extends Thread{

        private Counter counter;

        public IncreaseThread(Counter counter) {
            this.counter = counter;
        }

        @Override
        public void run() {
            System.out.println("After increase:" + counter.increase()+",trigger time:"+System.currentTimeMillis());
        }
    }

    /**
     * 獲取當(dāng)前值的線程
     */
    static class GetThread extends Thread{

        private Counter counter;

        public GetThread(Counter counter) {
            this.counter = counter;
        }

        @Override
        public void run() {
            System.out.println("Current:"+ counter.getCurrent()+",trigger time:"+System.currentTimeMillis());
        }
    }

}
執(zhí)行結(jié)果
Current:0,trigger time:1552487003845
After increase:1,trigger time:1552487008846
After increase:2,trigger time:1552487013848
結(jié)果分析

從測(cè)試結(jié)果可以得知

在兩個(gè)自增線程啟動(dòng)后,獲取當(dāng)前值的線程才啟動(dòng),但是獲取當(dāng)前值的線程是先被執(zhí)行完成了。

根據(jù)自增線程執(zhí)行完成的時(shí)間戳間隔可以得知,兩個(gè)自增線程是依次執(zhí)行的。

從而可以證明

synchronized并不是鎖定方法內(nèi)訪問(wèn)的變量

synchronized鎖定的是同一個(gè)監(jiān)視器對(duì)象監(jiān)視的代碼

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/73688.html

相關(guān)文章

  • (十四)java多線程之死鎖以及解決方案

    摘要:本人郵箱歡迎轉(zhuǎn)載轉(zhuǎn)載請(qǐng)注明網(wǎng)址代碼已經(jīng)全部托管有需要的同學(xué)自行下載引言多線程如果設(shè)計(jì)的不合理的話很可能就會(huì)出現(xiàn)死鎖當(dāng)兩個(gè)或者多個(gè)線程同事想要去獲取共享資源的鎖時(shí)但每個(gè)線程都要等其他線程把他們各自的鎖給釋放才能繼續(xù)運(yùn)行這就是死鎖出現(xiàn)死鎖必須具 本人郵箱: 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明網(wǎng)址 http://blog.csdn.net/tianshi_kcogithub: https://github...

    wendux 評(píng)論0 收藏0
  • Java中的讀寫鎖

    摘要:如果這時(shí)其中一個(gè)等待讀鎖的線程被方法喚醒,但因?yàn)榇藭r(shí)仍有請(qǐng)求寫鎖的線程存在,所以被喚醒的線程會(huì)再次進(jìn)入阻塞狀態(tài)。想要允許這樣的操作,要求這個(gè)線程是唯一一個(gè)擁有讀鎖的線程。 假設(shè)你的程序中涉及到對(duì)一些共享資源的讀和寫操作,且寫操作沒(méi)有讀操作那么頻繁。在沒(méi)有寫操作的時(shí)候,兩個(gè)線程同時(shí)讀一個(gè)資源沒(méi)有任何問(wèn)題,所以應(yīng)該允許多個(gè)線程能在同時(shí)讀取共享資源。但是如果有一個(gè)線程想去寫這些共享資源,就不...

    Alan 評(píng)論0 收藏0
  • 讀寫鎖的java實(shí)現(xiàn)

    摘要:如何維護(hù)狀態(tài)內(nèi)部維護(hù)的讀寫狀態(tài)是由位碼表示,高位為讀狀態(tài),表示持有讀鎖的線程數(shù),低位為寫狀態(tài),表示寫鎖的重入次數(shù),狀態(tài)的改變通過(guò)實(shí)現(xiàn),保證同步。寫鎖降級(jí)到讀鎖有時(shí)擁有寫鎖的線程也希望得到讀鎖。 ReentrantReadWriteLock 如何保證同步 Java中的可重入讀寫鎖ReentrantReadWriteLock是基于AQS(AbstractQueuedSynchronizer...

    233jl 評(píng)論0 收藏0
  • JAVA 7+ 實(shí)現(xiàn)自動(dòng)鎖(AutoLock)

    摘要:了解自動(dòng)鎖很早就受不了鎖的機(jī)制了每次都需要在去解鎖不僅代碼不美觀而且很麻煩我想能不能實(shí)現(xiàn)加鎖之后自動(dòng)解鎖如果是可以利用析構(gòu)函數(shù)實(shí)現(xiàn)但就想了想好像可以利用的特性對(duì)象只需要實(shí)現(xiàn)接口實(shí)現(xiàn)自動(dòng)鎖我了解如何利用特性寫一個(gè)自動(dòng)鎖那么下面我們開始真正 了解自動(dòng)鎖 很早就受不了 java 鎖的機(jī)制了,每次都需要在 finally 去解鎖, 不僅代碼不美觀,而且很麻煩 我想能不能實(shí)現(xiàn)加鎖之后自動(dòng)解鎖, ...

    Songlcy 評(píng)論0 收藏0
  • Java鎖機(jī)制了解一下

    摘要:底層是是通過(guò)對(duì)象,對(duì)象有自己的對(duì)象頭,存儲(chǔ)了很多信息,其中一個(gè)信息標(biāo)示是被哪個(gè)線程持有。當(dāng)一個(gè)線程執(zhí)行的代碼出現(xiàn)異常時(shí),其所持有的鎖會(huì)自動(dòng)釋放。 前言 回顧前面: 多線程三分鐘就可以入個(gè)門了! Thread源碼剖析 多線程基礎(chǔ)必要知識(shí)點(diǎn)!看了學(xué)習(xí)多線程事半功倍 只有光頭才能變強(qiáng)! 本文章主要講的是Java多線程加鎖機(jī)制,有兩種: Synchronized 顯式Lock 不得不嘮...

    hyuan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<