溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java 并發(fā)編程實戰(zhàn)重入鎖(子類同步方法調(diào)用父類的同步方法)

發(fā)布時間:2020-05-26 14:35:36 來源:網(wǎng)絡(luò) 閱讀:1046 作者:wx5c78c8b1dbb1b 欄目:編程語言
看如下代碼
public class Widget {

    public synchronized void doSomething () {
        System.out.println(this.toString()+"---------------------");
    }
}
public class LoggingWidget extends Widget {

    public synchronized void doSomething () {
        System.out.println(this.toString()+ ": calling doSomething");
        super.doSomething();
    }

    public static void main (String[] args) throws InterruptedException {
        for (int i = 0; i < 2; i++) {
            Thread thread = new Thread(() -> {
                Widget widget = new LoggingWidget();
                widget.doSomething();
            });
            thread.start();
        }
    }
}
  • 書上說如果內(nèi)置鎖不是可重入的,那么這段代碼將發(fā)生死鎖.我們先來理解一下什么是重入鎖,當(dāng)某個線程請求一個由某個線程持有的鎖時,發(fā)出的請求就會阻塞.然而,由于內(nèi)置鎖時可重入的,因此如果某個線程試圖獲得一個已經(jīng)由它自己持有的鎖,那么這個請求就會成功.
  • 理解了重入鎖,我們來看下幾種synchronized的鎖對象,同步方法的鎖對象:this,靜態(tài)的鎖對象:當(dāng)前類的class對象,同步代碼塊的鎖對象:任意對象.
  • 接下來我們來分析下代碼的執(zhí)行,假設(shè)線程A初始化了LoggingWidget 對象,接著去執(zhí)行doSomething 方法,由于doSomething 方法是非靜態(tài)同步方法,所以鎖對象就是this對象本身,獲取對象鎖,然后打印this.toString,接著調(diào)用super.doSomething 方法,由于是同步方法所以也需要獲取鎖對象,由于線程A已經(jīng)獲取了對象鎖,所以super.doSomething方法如果和doSomething 方法是同一個鎖對象就可以執(zhí)行,如果不是就獲取不到鎖,就會產(chǎn)生死鎖,永遠(yuǎn)獲取不到.筆者在這里不理解的問題是super.doSomething()是誰調(diào)用的,如果父類,那么這個同步方法的鎖對象就是父類本身,那么線程A不可能同時獲取兩個鎖對象.如果是子類調(diào)用的線程A已經(jīng)獲取了鎖對象,所以就可以執(zhí)行.
  • 我們來看下運(yùn)行結(jié)果:
    com.concyrrency.test.lock.LoggingWidget@2cb7a5c1: calling doSomething
    com.concyrrency.test.lock.LoggingWidget@2cb7a5c1---------------------
    com.concyrrency.test.lock.LoggingWidget@77df833b: calling doSomething
    com.concyrrency.test.lock.LoggingWidget@77df833b---------------------
  • 可以看到兩個線程的分別打印的this.toString都是一樣的,說明super.doSomething()的調(diào)用者是子類,而且內(nèi)置鎖是可以重入的.
  • 理解super關(guān)鍵字,在Java類中使用supper來引用分類的成分,用this來引用當(dāng)前的對象,如果一個類從另一個類繼承,new這個子類實例對象的時候,這個子類對象會含有一個父類對象,怎么去引用父類的對象了,使用super來停用,this指的是當(dāng)前對象的引用,super是當(dāng)前對象里面父類的引用.

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI