偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

3個(gè)月面試近300人,發(fā)現(xiàn)大部分人回答不出來(lái)這道題的重點(diǎn)!

開(kāi)發(fā) 前端
如果我們的程序使用synchronized關(guān)鍵字發(fā)生了死鎖時(shí),synchronized關(guān)鍵是是無(wú)法破壞“不可剝奪”這個(gè)死鎖的條件的。這是因?yàn)閟ynchronized申請(qǐng)資源的時(shí)候, 如果申請(qǐng)不到, 線(xiàn)程直接進(jìn)入阻塞狀態(tài)了, 而線(xiàn)程進(jìn)入阻塞狀態(tài), 啥都干不了, 也釋放不了線(xiàn)程已經(jīng)占有的資源。

在Java中提供了synchronized關(guān)鍵字來(lái)保證只有一個(gè)線(xiàn)程能夠訪(fǎng)問(wèn)同步代碼塊。既然已經(jīng)提供了synchronized關(guān)鍵字,那為何在Java的SDK包中,還會(huì)提供Lock接口呢?這是不是重復(fù)造輪子,多此一舉呢?今天,我們就一起來(lái)探討下這個(gè)問(wèn)題。

再造輪子?

既然JVM中提供了synchronized關(guān)鍵字來(lái)保證只有一個(gè)線(xiàn)程能夠訪(fǎng)問(wèn)同步代碼塊,為何還要提供Lock接口呢?這是在重復(fù)造輪子嗎?Java的設(shè)計(jì)者們?yōu)楹我@樣做呢?讓我們一起帶著疑問(wèn)往下看。

為何提供Lock接口?

很多小伙伴可能會(huì)聽(tīng)說(shuō)過(guò),在Java 1.5版本中,synchronized的性能不如Lock,但在Java 1.6版本之后,synchronized做了很多優(yōu)化,性能提升了不少。那既然synchronized關(guān)鍵字的性能已經(jīng)提升了,那為何還要使用Lock呢?

如果我們向更深層次思考的話(huà),就不難想到了:我們使用synchronized加鎖是無(wú)法主動(dòng)釋放鎖的,這就會(huì)涉及到死鎖的問(wèn)題。

死鎖問(wèn)題

如果要發(fā)生死鎖,則必須存在以下四個(gè)必要條件,四者缺一不可。

圖片圖片

  • 互斥條件

在一段時(shí)間內(nèi)某資源僅為一個(gè)線(xiàn)程所占有。此時(shí)若有其他線(xiàn)程請(qǐng)求該資源,則請(qǐng)求線(xiàn)程只能等待。

  • 不可剝奪條件

線(xiàn)程所獲得的資源在未使用完畢之前,不能被其他線(xiàn)程強(qiáng)行奪走,即只能由獲得該資源的線(xiàn)程自己來(lái)釋放(只能是主動(dòng)釋放)。

  • 請(qǐng)求與保持條件

線(xiàn)程已經(jīng)保持了至少一個(gè)資源,但又提出了新的資源請(qǐng)求,而該資源已被其他線(xiàn)程占有,此時(shí)請(qǐng)求線(xiàn)程被阻塞,但對(duì)自己已獲得的資源保持不放。

  • 循環(huán)等待條件

在發(fā)生死鎖時(shí)必然存在一個(gè)進(jìn)程等待隊(duì)列{P1,P2,…,Pn},其中P1等待P2占有的資源,P2等待P3占有的資源,…,Pn等待P1占有的資源,形成一個(gè)進(jìn)程等待環(huán)路,環(huán)路中每一個(gè)進(jìn)程所占有的資源同時(shí)被另一個(gè)申請(qǐng),也就是前一個(gè)進(jìn)程占有后一個(gè)進(jìn)程所深情地資源。

synchronized的局限性

如果我們的程序使用synchronized關(guān)鍵字發(fā)生了死鎖時(shí),synchronized關(guān)鍵是是無(wú)法破壞“不可剝奪”這個(gè)死鎖的條件的。這是因?yàn)閟ynchronized申請(qǐng)資源的時(shí)候, 如果申請(qǐng)不到, 線(xiàn)程直接進(jìn)入阻塞狀態(tài)了, 而線(xiàn)程進(jìn)入阻塞狀態(tài), 啥都干不了, 也釋放不了線(xiàn)程已經(jīng)占有的資源。

然而,在大部分場(chǎng)景下,我們都是希望“不可剝奪”這個(gè)條件能夠被破壞。也就是說(shuō)對(duì)于“不可剝奪”這個(gè)條件,占用部分資源的線(xiàn)程進(jìn)一步申請(qǐng)其他資源時(shí), 如果申請(qǐng)不到, 可以主動(dòng)釋放它占有的資源, 這樣不可剝奪這個(gè)條件就破壞掉了。

如果我們自己重新設(shè)計(jì)鎖來(lái)解決synchronized的問(wèn)題,我們?cè)撊绾卧O(shè)計(jì)呢?

解決問(wèn)題

了解了synchronized的局限性之后,如果是讓我們自己實(shí)現(xiàn)一把同步鎖,我們?cè)撊绾卧O(shè)計(jì)呢?也就是說(shuō),我們?cè)谠O(shè)計(jì)鎖的時(shí)候,要如何解決synchronized的局限性問(wèn)題呢?這里,我覺(jué)得可以從三個(gè)方面來(lái)思考這個(gè)問(wèn)題。

圖片圖片

(1)能夠響應(yīng)中斷。synchronized的問(wèn)題是, 持有鎖A后, 如果嘗試獲取鎖B失敗, 那么線(xiàn)程就進(jìn)入阻塞狀態(tài), 一旦發(fā)生死鎖, 就沒(méi)有任何機(jī)會(huì)來(lái)喚醒阻塞的線(xiàn)程。但如果阻塞狀態(tài)的線(xiàn)程能夠響應(yīng)中斷信號(hào), 也就是說(shuō)當(dāng)我們給阻塞的線(xiàn)程發(fā)送中斷信號(hào)的時(shí)候, 能夠喚醒它, 那它就有機(jī)會(huì)釋放曾經(jīng)持有的鎖A。這樣就破壞了不可剝奪條件了。

(2)支持超時(shí)。如果線(xiàn)程在一段時(shí)間之內(nèi)沒(méi)有獲取到鎖, 不是進(jìn)入阻塞狀態(tài), 而是返回一個(gè)錯(cuò)誤, 那這個(gè)線(xiàn)程也有機(jī)會(huì)釋放曾經(jīng)持有的鎖。這樣也能破壞不可剝奪條件。

(3)非阻塞地獲取鎖。如果嘗試獲取鎖失敗, 并不進(jìn)入阻塞狀態(tài), 而是直接返回, 那這個(gè)線(xiàn)程也有機(jī)會(huì)釋放曾經(jīng)持有的鎖。這樣也能破壞不可剝奪條件。

體現(xiàn)在Lock接口上,就是Lock接口提供的三個(gè)方法,如下所示。

// 支持中斷的API
void lockInterruptibly() throws InterruptedException;
// 支持超時(shí)的API
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
// 支持非阻塞獲取鎖的API
boolean tryLock();
  • lockInterruptibly()

支持中斷。

  • tryLock()方法

tryLock()方法是有返回值的,它表示用來(lái)嘗試獲取鎖,如果獲取成功,則返回true,如果獲取失?。存i已被其他線(xiàn)程獲取),則返回false,也就說(shuō)這個(gè)方法無(wú)論如何都會(huì)立即返回。在拿不到鎖時(shí)不會(huì)一直在那等待。

  • tryLock(long time, TimeUnit  unit)方法

tryLock(long time, TimeUnit  unit)方法和tryLock()方法是類(lèi)似的,只不過(guò)區(qū)別在于這個(gè)方法在拿不到鎖時(shí)會(huì)等待一定的時(shí)間,在時(shí)間期限之內(nèi)如果還拿不到鎖,就返回false。如果一開(kāi)始拿到鎖或者在等待期間內(nèi)拿到了鎖,則返回true。

也就是說(shuō),對(duì)于死鎖問(wèn)題,Lock能夠破壞不可剝奪的條件,例如,我們下面的程序代碼就破壞了死鎖的不可剝奪的條件。

public class TansferAccount{
    private Lock thisLock = new ReentrantLock();
    private Lock targetLock = new ReentrantLock();
    //賬戶(hù)的余額
    private Integer balance;
    //轉(zhuǎn)賬操作
    public void transfer(TansferAccount target, Integer transferMoney){
        boolean isThisLock = thisLock.tryLock();
        if(isThisLock){
            try{
                boolean isTargetLock = targetLock.tryLock();
                if(isTargetLock){
                    try{
                         if(this.balance >= transferMoney){
                            this.balance -= transferMoney;
                            target.balance += transferMoney;
                        }   
                    }finally{
                        targetLock.unlock
                    }
                }
            }finally{
                thisLock.unlock();
            }
        }
    }
}

例外,Lock下面有一個(gè)ReentrantLock,而ReentrantLock支持公平鎖和非公平鎖。

在使用ReentrantLock的時(shí)候, ReentrantLock中有兩個(gè)構(gòu)造函數(shù), 一個(gè)是無(wú)參構(gòu)造函數(shù), 一個(gè)是傳入fair參數(shù)的構(gòu)造函數(shù)。fair參數(shù)代表的是鎖的公平策略, 如果傳入true就表示需要構(gòu)造一個(gè)公平鎖, 反之則表示要構(gòu)造一個(gè)非公平鎖。如下代碼片段所示。

//無(wú)參構(gòu)造函數(shù): 默認(rèn)非公平鎖
public ReentrantLock() {
 sync = new NonfairSync();
} 
//根據(jù)公平策略參數(shù)創(chuàng)建鎖
public ReentrantLock(boolean fair){
 sync = fair ? new FairSync() : new NonfairSync();
}

鎖的實(shí)現(xiàn)在本質(zhì)上都對(duì)應(yīng)著一個(gè)入口等待隊(duì)列, 如果一個(gè)線(xiàn)程沒(méi)有獲得鎖, 就會(huì)進(jìn)入等待隊(duì)列, 當(dāng)有線(xiàn)程釋放鎖的時(shí)候, 就需要從等待隊(duì)列中喚醒一個(gè)等待的線(xiàn)程。如果是公平鎖, 喚醒的策略就是誰(shuí)等待的時(shí)間長(zhǎng), 就喚醒誰(shuí), 很公平;如果是非公平鎖, 則不提供這個(gè)公平保證, 有可能等待時(shí)間短的線(xiàn)程反而先被喚醒。 而Lock是支持公平鎖的,synchronized不支持公平鎖。

最后,值得注意的是,在使用Lock加鎖時(shí),一定要在finally{}代碼塊中釋放鎖,例如,下面的代碼片段所示。

try{
    lock.lock();
}finally{
    lock.unlock();
}

注:其他synchronized和Lock的詳細(xì)說(shuō)明,小伙伴們自行查閱即可。

責(zé)任編輯:武曉燕 來(lái)源: 冰河技術(shù)
相關(guān)推薦

2023-02-07 13:51:11

SQLupdate語(yǔ)句

2016-12-22 08:38:21

2015-11-25 10:48:44

JS閉包面試題

2011-12-26 17:13:18

iPad統(tǒng)計(jì)App

2018-11-25 21:53:10

人工智能AI開(kāi)發(fā)者

2025-01-26 16:04:09

2012-06-07 16:16:43

JavaScript

2023-09-21 15:20:49

算法開(kāi)發(fā)

2016-10-26 10:23:42

2022-05-18 09:49:26

MySQLID數(shù)據(jù)庫(kù)

2015-08-04 09:56:48

2021-10-14 06:51:54

SpringSecurityJWT

2023-08-07 11:56:43

模型人貨場(chǎng)數(shù)據(jù)

2024-12-31 08:58:45

2024-07-05 11:50:15

2025-06-04 11:06:54

比特幣區(qū)塊鏈挖礦

2019-11-20 08:30:07

架構(gòu)師軟件組織

2024-02-05 08:35:32

VuenextTickDOM

2017-11-08 10:21:54

iPhone X應(yīng)用劉海

2019-08-07 18:27:24

Chrome谷歌插件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)