接口BlockingQueue分析以及實現多個接口時的一點問題

在java併發包中,每種阻塞隊列BlockingQueue都有各自的特性,但是他們都是BlockingQueue的實現,因此分析併發包中的具體實現的BlockingQueue不如先了解BlockingQueue接口各方法的意義,然後具體分析某一個具體BlockingQueue隊列實現,最後推及所有BlockingQueue的特性(本篇本來打算和Queue接口分析作一篇放一塊,但是考慮到add、offer、remove、offer方法區別比較關鍵,因此拆開單獨)。

public interface BlockingQueue<E> extends Queue<E> {

    /*
    *  以下add方法和offer方法與接口Queue中的add和offer方法作用一樣,可以參見[Queue接口分析](https://mp.csdn.net/mdeditor/83145869#)
    *  但是,這裏爲什麼還要重複寫一遍呢?大神寫的,不知道爲什麼,但這裏體現了接口繼承中的一個特徵,
    *  即在接口的多繼承時,如果有相同的接口方法,最終JVM會把相同的方法合併成一個
    */
    boolean add(E e);

    boolean offer(E e);

    /* 
    *  BlockingQueue中新增了兩個往隊列中添加元素的方法,其目的是保證在多線程情況下能將元素新增到
    *  隊列中,put方法和這個offer方法的區別在於,一個是死等,一個是有時間限制的等待,但是從方法的定義上,
    *  put和這個offer方法都拋出了InterruptedException,說明這個等待過程是支持打斷的
    * 
    */
    void put(E e) throws InterruptedException;

    boolean offer(E e, long timeout, TimeUnit unit)
        throws InterruptedException;

    /*
    *  take方法和poll方法新增了等待機制,即等待隊列頭部元素可以被刪除,
    *  兩者的區別在於,poll方法添加了時間限制,兩者都拋出了InterruptedException異常
    *  這裏有個問題,就是BlockingQueue接口繼承了Queue接口,但Queue接口中沒有拋出異常,BlockingQueue
    *  接口中確有拋出異常,名字一樣,最終以誰爲準,最近的,也就是BlockingQueue
    */
    E take() throws InterruptedException;

    E poll(long timeout, TimeUnit unit)
        throws InterruptedException;
        
    /*
    *  剩餘的容量,不過用處不大,在多線程情況,剩餘容量是永遠在變的
    */
    int remainingCapacity();

    /*
    *  刪除隊列中的元素o
    */
    boolean remove(Object o);

   /*
    *  判斷隊列中是否含有元素o
    */
    public boolean contains(Object o);

    /*
    *  以下兩個方法都是批量拽取元素到另一個Collection中方法,BlockingQueue也是一個Collection,因
    *  爲Queue繼承至Collection
    */
    int drainTo(Collection<? super E> c);

    int drainTo(Collection<? super E> c, int maxElements);
}

結論:
BlockingQueue相對於Queue新增了對待操作成功能力,添加元素和刪除元素,同時支持超時機制,支持打斷,另外支持批量拽取。

但這裏有一個小問題,如果一個接口多繼承兩個不同的接口,而這兩個不同接口各有一個方法名相同但是一個聲明瞭拋出異常,一個沒有聲明拋出異常,在實現時,需不需要實現兩個方法?如果不需要,那實現哪個?因爲既沒法當作重寫,也沒法當作重載

Interface1.java

public interface Interface1 {

     void test1();
     void test2();
     void test()  throws Exception ;
}

Interface2.java

public interface Interface2 {

    void test();
}

ImplementClass.java

public class ImplementClass implements Interface2, Interface1 {

    @Override
    public void test1() {
        
    }

    @Override
    public void test2() {
    
    }

    @Override
    public void test(){
        
    }
}

以上這種方式是可以的。
一旦在ImplementClass類的test方法中加上 throws Exception聲明,將報not compatible with throws clause in Interface2.test(),即不匹配Interface2的test方法了,這個方法沒有聲明拋異常,如果Interface2的test方法加上拋異常的聲明,即Interface2和Interface1的test方法在此時都加上拋異常聲明,即可以。

因此說明,在實現多個接口時,多個接口中有方法名和參數一樣的方法,最好保證拋異常情況一致,如果不一致的化,實現類中實現方法不能寫拋異常聲明,不然會出現匹配錯誤。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章