第五章 定時器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表示遞歸。
線程有序性:改造代碼的方式才能實作;