當(dāng)線程請(qǐng)求一個(gè)由其它線程持有的對(duì)象鎖時(shí),該線程會(huì)阻塞,而當(dāng)線程請(qǐng)求由自己持有的對(duì)象鎖時(shí),如果該鎖是重入鎖,請(qǐng)求就會(huì)成功,否則阻塞。
java中獲取鎖的操作的粒度是“線程”,而不是“調(diào)用”,即不是每一次調(diào)用都是建立一個(gè)鎖。
重入鎖的一種實(shí)現(xiàn)方法是為每個(gè)鎖關(guān)聯(lián)一個(gè)線程持有者和計(jì)數(shù)器,當(dāng)計(jì)數(shù)器為0時(shí)表示該鎖沒有被任何線程持有,那么任何線程都可能獲得該鎖而調(diào)用相應(yīng)的方法;當(dāng)某一線程請(qǐng)求成功后,JVM會(huì)記下鎖的持有線程,并且將計(jì)數(shù)器置為1;此時(shí)其它線程請(qǐng)求該鎖,則必須等待;而如果同一個(gè)線程再次請(qǐng)求這個(gè)鎖,就可以再次拿到這個(gè)鎖,同時(shí)計(jì)數(shù)器會(huì)遞增;當(dāng)線程退出同步代碼塊時(shí),計(jì)數(shù)器會(huì)遞減,如果計(jì)數(shù)器為0,則釋放該鎖。
看下面的例子,正是由于java的內(nèi)置鎖是可重入的,所以下面這段代碼不會(huì)發(fā)生死鎖:
public class Child extends Father{
public static void main(String[] args) {
new Child().doSomething();
}
public synchronized void doSomething(){
System.out.println("child");
super.doSomething();
}
}
class Father{
public synchronized void doSomething(){
System.out.println("Father");
}
}
輸出結(jié)果:
child
Father
重入的錯(cuò)誤理解:

一本正經(jīng)的胡說八道
原文鏈接
正確理解:



知乎問題鏈接