一、死鎖
所謂死鎖: 是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過(guò)程中,因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象,若無(wú)外力作用,它們都將無(wú)法推進(jìn)下去。百科百科
當(dāng)兩個(gè)以上的運(yùn)算單元,雙方都在等待對(duì)方停止運(yùn)行,以取得系統(tǒng)資源,但是沒(méi)有一方提前退出時(shí),這種狀況,就稱為死鎖。維基百科
1. 順序死鎖
最少有兩個(gè)鎖,一個(gè)線程獲取到A鎖需要獲取B鎖才能進(jìn)行操作,而另外一個(gè)線程獲取到了B鎖,需要獲取A鎖才能執(zhí)行操作,這種情況下容易出現(xiàn)順序死鎖。
[java]view plaincopy
publicclassLeftRightDeadlock?{
privatefinalObject?left?=newObject();
privatefinalObject?right?=newObject();
publicvoidleftRight()?{
synchronized(left)?{
synchronized(right)?{
//?doSomething();
}
}
}
publicvoidrightLeft()?{
synchronized(right)?{
synchronized(left)?{
//?doSomething();
}
}
}
}
2. 動(dòng)態(tài)的鎖順序死鎖
[java]view plaincopy
publicvoidtransferMoney(Account?fromAccount,?Account?toAccount,?DollarAmount?anount)
throwsInsufficientResourcesException?{
synchronized(fromAccount)?{
synchronized(toAccount)?{
if(fromAccount.getBalance().compareTo(amount)?<0)?{
thrownewInsufficientResourcesException();
}else{
fromAccount.debit(anount);
toAccount.credit(anount);
}
}
}
}
A: transferMoney(myAccount, yourAccount, 10);
B: transferMoney(yourAccount, myAccount, 20);
由外部傳入的變量所有鎖的條件,但是由以上傳入的變量可以看到,這種情況下會(huì)出現(xiàn)一個(gè)線程先獲取myAccount鎖在申請(qǐng)yourAccount鎖,而另外一個(gè)線程相反先獲取yourAccount鎖在申請(qǐng)myAccount鎖。
[java]view plaincopy
privatestaticfinalObject?tieLock?=newObject();
publicvoidtransferMoney(finalAccount?fromAccount,finalAccount?toAccount,finalDollarAmount?anount)
throwsInsufficientResourcesException?{
classHelper{
publicvoidtransfer()throwsInsufficientResourcesException?{
if(fromAccount.getBalance().compareTo(amount)?<0){
thrownewInsufficientResourcesException();
}else{
fromAccount.debit(anount);
toAccount.credit(anount);
}
}
}
intfromHash?=?System.identityHashCode(fromAccount);
inttoHash?=?System.identityHashCode(toAccount);
if(fromHash?<?toHash){
synchronized(fromAccount){
synchronized(toAccount)?{
newHelper().transfer();
}
}
}elseif(fromHash?>??toHash){
synchronized(toAccount){
synchronized(fromAccount)?{
newHelper().transfer();
}
}
}else{
synchronized(tieLock)?{
synchronized(fromAccount)?{
synchronized(toAccount)?{
newHelper().transfer();
}
}
}
}
}
3. 在協(xié)作對(duì)象之間發(fā)生的死鎖
[java]view plaincopy
classTaxi?{
privatePoint?location,?destination;
privatefinalDispatcher?dispatcher;
publicTaxi(Dispatcher?dispatcher)?{
this.dispatcher?=?dispatcher;
}
publicsynchronizedPoint?getLocation(){
returnlocation;
}
publicsynchronizedvoidsetLocation(Point?location){
this.location?=?location;
if(location.equals(destination)){
dispatcher.notifyAvaliable(this);
}
}
}
classDispatcher?{
privatefinalSet?taxis;
privatefinalSet?avaliableTaxis;
publicDispatcher(){
taxis?=newHashSet();
avaliableTaxis?=newHashSet();
}
publicsynchronizedvoidnotifyAvaliable(Taxi?taxi)?{
avaliableTaxis.add(taxi);
}
publicsynchronizedImage?getImage(){
Image?image?=newImage();
for(Taxi?t?:taxis){
image.drawMarker(t.getLocation());
}
returnimage;
}
}
4. 開(kāi)放調(diào)用
-- 待填充
5. 資源死鎖
外部鎖常被忽視而導(dǎo)致死鎖,例如數(shù)據(jù)庫(kù)的鎖
1. 支持定時(shí)的死鎖
存在一些預(yù)防死鎖的手段,比如Lock的tryLock,JDK 7中引入的Phaser等。
2. 通過(guò)線程轉(zhuǎn)儲(chǔ)信息來(lái)分析死鎖
通過(guò)Dump線程的StackTrace,例如linux下執(zhí)行命令 kill -3 ,或者jstack –l ,或者使用Jconsole連接上去查看線程的StackTrace,由此來(lái)診斷死鎖問(wèn)題。
1. 饑餓
2. 糟糕的響應(yīng)性
3. 活鎖
使用支持CAS的數(shù)據(jù)結(jié)構(gòu),避免使用鎖,如:AtomicXXX、ConcurrentMap、CopyOnWriteList、ConcurrentLinkedQueue
死鎖經(jīng)常是無(wú)法完全避免的,鴕鳥(niǎo)策略被很多基礎(chǔ)框架所采用。
存在檢測(cè)死鎖的辦法
以上就是我推薦給Java開(kāi)發(fā)者們的一面試經(jīng)典知識(shí)。但是這些知識(shí)里面并沒(méi)有太多Java全棧、Java晉階、JAVA架構(gòu)之類的題,不是我不推薦,而是希望大家更多的從基本功做起,打好基礎(chǔ),太多復(fù)雜的內(nèi)容一會(huì)兒也說(shuō)不明白。
好了同學(xué)們,我能介紹的也都全部介紹完給你們了,如果下獲得更多JAVA教學(xué)資源,可以選擇來(lái)我們這里共同交流,群:240448376,很多大神在這里切磋學(xué)習(xí),不懂可以直接問(wèn),晚上還有大牛免費(fèi)直播教學(xué)。
注:加群要求
1、具有一定工作經(jīng)驗(yàn)的,面對(duì)目前流行的技術(shù)不知從何下手,需要突破技術(shù)瓶頸的可以加,有些應(yīng)屆生和實(shí)習(xí)生也可以加。
2、在公司待久了,過(guò)得很安逸,但跳槽時(shí)面試碰壁。需要在短時(shí)間內(nèi)進(jìn)修、跳槽拿高薪的可以加。
3、如果沒(méi)有工作經(jīng)驗(yàn),但基礎(chǔ)非常扎實(shí),對(duì)java工作機(jī)制,常用設(shè)計(jì)思想,常用java開(kāi)發(fā)框架掌握熟練的,可以加。
4、覺(jué)得自己很牛B,一般需求都能搞定。但是所學(xué)的知識(shí)點(diǎn)沒(méi)有系統(tǒng)化,很難在技術(shù)領(lǐng)域繼續(xù)突破的可以加。
5.阿里Java高級(jí)大牛直播講解知識(shí)點(diǎn),分享知識(shí),多年工作經(jīng)驗(yàn)的梳理和總結(jié),帶著大家全面、科學(xué)地建立自己的技術(shù)體系和技術(shù)認(rèn)知!
PS:現(xiàn)在主要講解的內(nèi)容是(反射原理、枚舉原理與應(yīng)用、注解原理、常用設(shè)計(jì)模式、正規(guī)表達(dá)式高級(jí)應(yīng)用、JAVA操作Office原理詳解、JAVA圖像處理技術(shù),等多個(gè)知識(shí)點(diǎn)的詳解和實(shí)戰(zhàn))
6.小號(hào)或者小白之類加群一律不給過(guò),謝謝。
最后,每一位讀到這里的網(wǎng)友,感謝你們能耐心地看完。覺(jué)得對(duì)你有幫助可以給個(gè)喜歡!希望在成為一名更優(yōu)秀的Java程序員的道路上,我們可以一起學(xué)習(xí)、一起進(jìn)步