1. 程式人生 > >關於“關鍵字synchronized不能被繼承”的一點理解。

關於“關鍵字synchronized不能被繼承”的一點理解。

網上看到很多對關鍵字synchronized繼承性的描述只有一句"關鍵字synchronized不能被繼承",並沒有描述具體場景,於是自己做了以下測試。

//父類

public class Super {

    static Logger logger = Logger.getLogger(Super.class);

    // 同步方法
    @SuppressWarnings("static-access")
    public synchronized void testMothed() {
         try {
                Thread.currentThread().sleep(5000);//休眠5秒。
         } catch (InterruptedException e) {
                e.printStackTrace();
         }
          logger.info(Thread.currentThread().getName() + "," + this);
    }

}

//子類1

public class Sub1 extends Super {

    // 不重寫父類的同步方法
}

//子類2

public class Sub2 extends Super {

    // 重寫父類的同步方法,但不加synchronized。

   @SuppressWarnings("static-access")
    public void testMothed() {
        try {
               Thread.currentThread().sleep(3000);//為區別與父類中休眠時間,改為3秒。
        } catch (InterruptedException e) {
                  e.printStackTrace();
        }
        logger.info(Thread.currentThread().getName() + "," + this);
    }
}

//測試類

public class SynchronizedTest {

    static Logger logger = Logger.getLogger(SynchronizedTest.class);

    public static void main(String[] args) throws Exception {
            // 子類物件1
            final Sub1 sub1 = new Sub1();
            final int count = 5;
            // 建立count個不同執行緒,呼叫子類物件1同一方法
            for (int i = 0; i < count; i++) {
                   new Thread() {
                           public void run() {
                                  sub1.testMothed();
                           }
                    }.start();
              }

             // 讓上面所有子執行緒有足夠時間執行結束
             TimeUnit.SECONDS.sleep((count+1)*5);

              logger.info("===============================================");

             // 子類物件2
             final Sub2 sub2 = new Sub2();
             // 建立count個不同執行緒,呼叫子類物件2同一方法
             for (int i = 0; i < count; i++) {
                     new Thread() {
                          public void run() {
                               sub2.testMothed();
                         }
                     }.start();
              }
    }
   
}

執行結果:

2013-12-03 12:40:18,043 [INFO]----> Thread-0,java_lang.thread_synchronized.[email protected]
2013-12-03 12:40:23,044 [INFO]----> Thread-4,java_lang.thread_synchronized.[email protected]
2013-12-03 12:40:28,044 [INFO]----> Thread-3,java_lang.thread_synchronized.[email protected]
2013-12-03 12:40:33,044 [INFO]----> Thread-2,java_lang.thread_synchronized.[email protected]
2013-12-03 12:40:38,045 [INFO]----> Thread-1,java_lang.thread_synchronized.[email protected]
2013-12-03 12:40:43,044 [INFO]----> ===============================================
2013-12-03 12:40:46,045 [INFO]----> Thread-6,java_lang.thread_synchronized.[email protected]
2013-12-03 12:40:46,045 [INFO]----> Thread-7,java_lang.thread_synchronized.[email protected]
2013-12-03 12:40:46,045 [INFO]----> Thread-5,java_lang.thread_synchronized.[email protected]
2013-12-03 12:40:46,046 [INFO]----> Thread-8,java_lang.thread_synchronized.[email protected]
2013-12-03 12:40:46,046 [INFO]----> Thread-9,java_lang.thread_synchronized.[email protected]

從上面可以看出,

不同執行緒對子類Sub1的同一物件sub1,呼叫testMothed,有同步效果,分別進入該方法,分別等待5秒。(紅色與紅色時間差)

不同執行緒對子類Sub2的同一物件sub2,呼叫testMothed,沒有同步效果,所有執行緒同時進入該方法並同時等待3秒(藍色到綠色時間差),然後同時執行(綠色時間一樣)。

因此,對"關鍵字synchronized不能被繼承",完整描述應該是:

1、子類繼承父類時,如果沒有重寫父類中的同步方法,子類同一物件,在不同執行緒併發呼叫該方法時,具有同步效果。

2、子類繼承父類,並且重寫父類中的同步方法,但沒有新增關鍵字synchronized,子類同一物件,在不同執行緒併發呼叫該方法時,不再具有同步效果,這種情形即是"關鍵字synchronized不能被繼承"的轉述。(貌似很多人在這一點上存在疑惑)。

相關推薦

關於“關鍵字synchronized不能繼承”的一點理解

網上看到很多對關鍵字synchronized繼承性的描述只有一句"關鍵字synchronized不能被繼承",並沒有描述具體場景,於是自己做了以下測試。 //父類 public class Super {     static Logger logger = Logger.getLogger(Super.

談一談我對java單繼承和多繼承理解

今天終於重拾書本,感覺好久好久沒有認真看過書了樣。好了不說廢話了。 偶是菜鳥,可能理解有誤。高手們指點指點哦。 今天看那書上說:java是但繼承,並不支援多繼承,後來又講到java支援多繼承,是在介面的基礎上實現多繼承。 總的來說還是不支援多繼承,要通過其他方式來彌補jav

deeplabcv2 的 Atrous Convolution(帶孔卷機核),感受野,及tensorflow實現crf的一點理解

首先是因為做影象分割,所以使用deeplab。思想基本和fcn一樣。先卷機提取特徵,然後闊尺寸至原影象大小。 普通fcn先把影象padding至很大(據說是邊緣補100個0),然後一層層下來,pool (stride=2)或者是卷機( stride=2)5次,影象縮小了32

月薪上萬,卻依然不世界所理解程式設計師訪談(二)

點選上方關注我們,讓小care關愛你! 有一個“月入五萬卻像月入五千樣子”的群體,以“收入高”、“腦回路簡單”、“一成不變”等

理解構造器為什麼不能繼承

不能,因為子類繼承父類的時候,先執行父類建構函式;具體的說就是執行父類時就會先“呼叫”父類的建構函式,注意“呼叫”和繼承不是一個含義,實質上是“自動執行”。 繼承(extends)的含義其實是“擴充套件”,子類完全沒必要擴充套件父類的建構函式,因為反正每次調子類的時候都會“自動執行”它父類的建構函式

描述下你對js閉包面向對象、繼承理解

apply prototype 滿足 編程範式 函數 details 內存 全局 訪問控制 1)閉包理解: 個人理解:閉包就是能夠讀取其他函數內部變量的函數; 使用閉包主要是為了設計私有的方法和變量。閉包的優點是可以避免全局變量的汙染,缺點是閉包會常駐內存,會增大內存使

描述下你對js閉包面向物件、繼承理解

1)閉包理解:   個人理解:閉包就是能夠讀取其他函式內部變數的函式; 使用閉包主要是為了設計私有的方法和變數。閉包的優點是可以避免全域性變數的汙染,缺點是閉包會常駐記憶體,會增大記憶體使用量,使用不當很容易造成記憶體洩露。在js中,函式即閉包,只有函式才會產生作用域的概念 閉包有三

學習Java之對關鍵字break和continue的一點理解

我們都知道關鍵字 ——   break 是 預設跳出當前距離此 break 最近的一個 for / while 迴圈語句塊 或  switch 開關語句塊; 例-1:跳出迴圈 for(;;) { while(true)

面試:對封裝、繼承、多型的理解

1.封裝 封裝:就是隱藏物件的屬性和實現細節,僅對外提供公共訪問方式。     封裝的好處:隱藏類的實現細節;讓使用者只能通過程式設計師規定的方法來訪問資料;可以方便的加入存取控制語句,限制不合理操作. 封裝時的許可權控制符區別如下: 1 /* 2

關鍵字static與單例模式的一點理解

static是java語言中的一個關鍵字,表示一個靜態修飾符,修飾符比較容易理解,靜態修飾符又有什麼特點呢,首先程式中的任何變數或者程式碼都是在編譯時,由系統自動分配記憶體來儲存的,而靜態的特點就是指,在編譯後所分配的記憶體會一直存在,直到程式退出是才會釋放這個

@DomainEvents和@AfterDomainEventPublication註解使用及一點點點理解

問題 剛才在讀Spring-data-mongodb的文件,讀到7.7的時候就發現了@DomainEvents 和@AfterDomainEventPublication這麼兩個註解。 就看懂了最後一句每次呼叫Spring Data儲存庫的save(…)

關於Volatile關鍵字一點理解

今天在看ImageLoader的原始碼的時候看到ImageLoader類裡面的單例模式的類物件宣告為<span style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size:

java中繼承理解,super關鍵字,方法的重寫和過載以及注意事項理解

一、類的繼承理解 在java中類的繼承是指:在一個現有類的基礎之上去構建一個新的類,構建出來的新的類被稱為子類,現有類是父類,子類會自動擁有父類所有可繼承的屬性和方法。繼承類是現有類的更具體一些,繼承類可能只擁有一部分父類的屬性和方法。 如圖,這就表示了繼承類是父類的一種更具體形式

Java構造方法繼承一點理解

1.Java中所有的類都是繼承自Object(不要以為你寫一個類沒有寫 extends Object 就以為你沒有繼承了,一定要有這個概念),Object類有個一個無參構造方法,所以我們在寫一個類的時候如果沒有新增構造方法,Java會預設幫我們新增上; 如果自己定義了構造方法,java則不再幫我們建立,如果此

Java同步關鍵字Synchronized深入理解

題記 講講寫這篇部落格的原因,因為自認為對synchronized這個關鍵字很瞭解了,前幾天和一個剛好在找工作的朋友聊到了這個。結果他把面試遇到的一個問題給我出了出來,當我蒙圈的那一刻才懂得自己之前的瞭解只是皮毛。 正文 對於synchronized這

關於進行條件篩選的SQL關鍵字一點理解

概述 一般能夠用於條件篩選的有三種: ON: 聯結(join)篩選 WHERE: 一般條件篩選 HAVING: 分組後的條件篩選 ON JOIN – ON 語句的執行順序: 例句: SELECT * FROM A LEFT JO

css中那些屬性可以繼承

mil 屬性 ria ext direct tran ade weight -s 主要的有: 字體相關:line-height, font-family, font-size, font-style, font-variant, font-weight, font 文本相關

JavaScript es6 class類的理解

實例 leo super 提升 fin .info asc style function 在本篇文章我將會把我對JavaScript es6新特性class類的理解。本著互聯網的分享精神,我就將我自己的理解分享給大家。 使用es寫一個類(構造函數) 在es5中大家一般都這

JavaScript ES6 promiss的理解

res 是我 服務器 同步 重寫 清晰 ajax 並不會 ret 本著互聯網的分享精神,我將我對promise的理解分享給大家。 JavaScript ES6的promise方法主要應用在處理異步函數返回的結果,註意他不是將異步函數轉換為同步函數,而是等異步函數有結果時在

用C++設計一個不能繼承的類(轉)

它的 設計 指定 基於 構造 重寫 rtu 構造函數、析構函數 析構函數 在Java 中定義了關鍵字final,被final修飾的類不能被繼承。 首先想到的是在C++中,子類的構造函數會自動調用父類的構造函數。同樣,子類的析構函數也會自動調用父類的析構函數。要想一個類不能