天天看點

《Java多線程程式設計核心技術》讀書筆記

第五章 定時器Timer

寫在前面,現在基本上很少使用JDK自帶的Timer和TimerTask,因為各種問題:

  • 時間計算不準确:timer是以絕對時間計算定時任務的,是以會受到系統時間的影響。
  • 單次隻能執行一次任務:每次隻從隊列中拿出一個任務執行。
  • 前面的任務出現錯誤的話後面的任務不會執行。

    同一個TimerTask對象不能夠被schedule兩次,否則會抛出TimerTask is scheduled already。

    當一個TimerTask被cancel的時候需要重新進行執行個體化才可以schedule,否則會抛出出TimerTask is canceled。

    一般用quartz或者concurrent包下面的ScheduledThreadPoolExecutor或者spring的ThreadPoolTaskExecutor來代替。故本章節的内容大緻看看即可,無需深究。

TimerTask 以列隊的形式一個個被順序執行,故而後面的任務的運作時間會被延遲;

TimerTask 類的cancel方法将自身從任務隊列中移除,其他任務不受影響;

Timer 類的cancel方法是将任務隊列的全部任務清空;但是這個cancel方法有時不一定會停止執行計劃任務,而是正常執行;

方法 schedule 和 scheduleAtFixedRate 的主要差別在于不延遲的情況:

schedule:如果執行任務的時間沒有被延遲,則下一次任務的執行時間參考上一次任務的開始時間來計算;schedule方法不具有追趕執行性

scheduleAtFixedRate:如果執行任務的時間沒有被延遲,則下一次任務的執行時間參考的上一次任務的結束時間來計算;scheduleAtFixedRate 方法具有追趕執行性;

第六章 單例模式與多線程

立即加載,餓漢模式,在調用方法之前,執行個體已經被建立;

延遲加載,懶漢模式,在調用get()方法時,執行個體才被建立,在get方法裡面進行new執行個體化,多線程環境下會出現多個執行個體的情況;僅僅使用synchronized語句塊,不能解決問題;需要使用DCL雙重檢查鎖的機制;

另外,還可以使用靜态内部類的方式來實作單例模式;但是,遇到序列化對象時,單例模式會被破壞,此時需要重寫**readResolve()**方法,傳回建立的單例;

靜态代碼塊中的代碼在使用類時已經執行,也可以用來實作單例模式:

public class Singleton {
    private static Singleton instance = null;
    private Singleton() {
    }
    static {
        instance = new Singleton();
    }
    public static Singleton getInstance() {
        return instance;
    }
}      

最後就是使用枚舉類來實作單例模式;

第七章 拾遺增補

方法與狀态關系示意圖:

NEW:線程執行個體化之後還沒有執行過start方法時的狀态;

RUNNABLE:線程進入運作的狀态;

TERMINATED:線程被銷毀的狀态;

TIMED_WAITING:線程執行Thread.sleep()方法,等待狀态;

BLOCKED:某一個線程在等待鎖的時候;

WAITING:線程執行Object.wait()方法之後所處的狀态;

線程組

線程對象關聯線程組:1級關聯;

線程對象關聯線程組:多級關聯,不推薦,結構設計複雜反而不利于線程對象的管理;

自動歸屬就是自動歸檔到目前線程組;

擷取根線程組:Thread.currentThread().getThreadGroup().getParent().getName(),JVM的根線程組就是system,再取其父線程組則抛NPE。

線程組内的線程批量停止:調用線程組ThreadGroup的interrupt()方法,将組内的所有正在運作的線程批量停止。

遞歸以及非遞歸取得組内對象:ThreadGroup.enumerate()方法,入參true表示遞歸。

線程有序性:改造代碼的方式才能實作;

繼續閱讀