1. 程式人生 > >《Java併發程式設計的藝術》筆記五——Java執行緒基礎.md

《Java併發程式設計的藝術》筆記五——Java執行緒基礎.md

0.執行緒的狀態

名稱 說明
New 即執行緒剛剛建立,而並未執行
Runnable 執行狀態,Java執行緒將作業系統中的就緒和執行兩種狀態籠統的稱作“執行中”
Blocked 阻塞狀態,表示執行緒阻塞於鎖
Waiting 等待狀態,表示執行緒進入等待狀態,需要等待其他執行緒做出一些動作(通知或中斷)
TimeWaiting 超時等待狀態,在指定時間內自行返回
Termicaled 終止狀態,表示當前執行緒已經執行完畢

1.啟動和終止執行緒

1.1構造執行緒
執行緒物件在構造的時候,需要提供喜愛能撐所需要的屬性,例如執行緒所屬的執行緒組,執行緒的優先順序,是否是Daemon(守護)執行緒等。
我們擷取Thread類中對執行緒的初始化部分:

private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc) {
    if (name == null) {
        throw new NullPointerException("name cannot be null");
    }
    this.name = name;
    Thread parent = currentThread();//當前執行緒就是該執行緒的父執行緒
    this
.group = g; this.daemon = parent.isDaemon(); this.priority = parent.getPriority(); this.target = target; setPriority(priority); //將父執行緒的InheritableThreadLocal複製過來 if (parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); /* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize; /* Set thread ID */ tid = nextThreadID(); }

一個新構造的執行緒物件,是由其parent執行緒來進行空間分配的,而child執行緒繼承了parent是否為Daemon,優先順序和載入資源的contextClassLoader以及可繼承的ThreadLocal,同時還會分配一個唯一的ID來標示這個child執行緒。初始化好之後,在堆記憶體中等待著執行。

1.2 啟動執行緒

呼叫start方法就可以啟動執行緒。若無其他設定,呼叫start方法後,執行緒進入到就緒狀態,CPU有資源時即執行執行緒的run方法。

1.3 執行緒中斷

中斷表示一個執行中的執行緒是否被其他執行緒進行了中斷操作。中斷好比其他執行緒對該執行緒打了個招呼,其他執行緒通過呼叫該執行緒的interrupt()函式對其進行中斷操作。

執行緒通過檢查自身是否中斷進行響應,執行緒通過方法isInterrupted()來判斷是否被中斷,也可以呼叫靜態方法Thread.interruted()對當前執行緒的中斷標示位進行復位。
如果該執行緒已處於終結狀態,即使該執行緒被中斷過,則isInterrupted()也會返回false;

1.4 安全的終止執行緒

中斷狀態是執行緒的一個標示位,最適合用來取消或停止任務。除了中斷以外,還可以用一個boolean變數來控制是否需要終止任務並終止執行緒。

以下是一個例子:


public class Shutdown {
    public static void main(String[] args) {
        Runner one = new Runner();
        Thread count = new Thread(one,"CounttThread");
        count.start();
        SleepUtils.second(1);
        count.interrupt();
        Runner two = new Runner();
        count = new Thread(two,"CountThread2");
        count.start();
        SleepUtils.second(1);
        two.cancel();
    }

    static class Runner implements Runnable {
        private volatile boolean on = true;
        private long count;

        @Override
        public void run() {
            while (on && !Thread.currentThread().isInterrupted()) {
                count++;
            }
            System.out.println("count=" + count);
        }

        public void cancel() {
            on = false;
        }
    }

}