Java 併發程式設計(六) -- ThreadPoolExecutor中的Worker

我很醜發表於2020-03-11

1. 類的定義

private final class Worker extends AbstractQueuedSynchronizer implements Runnable
複製程式碼

從類的定義中可以看出

  • Worker繼承了AbstractQueuedSynchronizer(AQS)
  • Worker實現了Runnable介面

2. 欄位屬性

//序列化版本號
private static final long serialVersionUID = 6138294804551838833L;
//當前工作執行的執行緒
final Thread thread;
//工作執行緒要執行的任務
Runnable firstTask;
//已經完成的任務統計
volatile long completedTasks;
複製程式碼

從欄位屬性可以看出

  • Worker中包含了一個Thread物件,這個是Worker執行的核心
  • Worker中包含了一個Runnable物件,Thread執行的任務目標
  • Worker儲存了完成任務的統計

3. 構造方法

//傳入一個Runnable物件
Worker(Runnable firstTask) {
    		//設定同步狀態,這個是AQS的方法
            setState(-1); // inhibit interrupts until runWorker
    		//設定執行任務,可能為null
            this.firstTask = firstTask;
    		//使用執行緒工廠建立一個新的執行緒
            this.thread = getThreadFactory().newThread(this);
        }
複製程式碼

構造方法主要是做一些初始化操作

4. 方法

run 方法

//啟動worker
public void run() {
    		//呼叫ThreadPoolExecutor的runWork方法,迴圈去工作佇列中獲取任務執行
            runWorker(this);
        }
複製程式碼

isHeldExclusively 方法

//判斷當前是否處於上鎖狀態,true 未上鎖狀態, false 上鎖狀態
protected boolean isHeldExclusively() {
    		//state 0:unlocked state 1:locked state
            return getState() != 0;
        }
複製程式碼

tryAcquire 方法

//嘗試上鎖
protected boolean tryAcquire(int unused) {
    		//使用CAS設定state值為1
            if (compareAndSetState(0, 1)) {
                //設定當前執行緒獨佔訪問方式設定為呼叫執行緒
                //設定搶到鎖的執行緒未當前呼叫執行緒,這個是AQS的方法
                setExclusiveOwnerThread(Thread.currentThread());
                //成功返回true
                return true;
            }
    		//CAS失敗返回false
            return false;
        }
複製程式碼

tryRelease 方法

//嘗試解鎖
protected boolean tryRelease(int unused) {
    		//把當前執行緒獨佔訪問方式設定為null,這個是AQS的方法
    		//把當前搶到鎖的執行緒置為null
            setExclusiveOwnerThread(null);
    		//state設定為0,
            setState(0);
    		//返回true
            return true;
        } 
複製程式碼

lock 方法

//上鎖
public void lock()  { 
    //呼叫acquire方法,這個是AQS的方法
    acquire(1); 
}
複製程式碼

tryLock 方法

//嘗試上鎖
public boolean tryLock()  { 
    //呼叫tryAcquire方法
    return tryAcquire(1); 
}
複製程式碼

unlock 方法

//解鎖
public void unlock()  { 
    //呼叫release方法,這個是AQS的方法
    release(1); 
}
複製程式碼

isLocked 方法

//檢查是否有所
public boolean isLocked() { 
    //呼叫isHeldExclusively方法判斷
    return isHeldExclusively(); 
}
複製程式碼

interruptIfStarted 方法

//中斷工作的執行緒
void interruptIfStarted() {
            Thread t;
    		//getState() >= 0 表示不是初始狀態,初始狀態為-1
    		//當前執行緒不為null並且不是中斷狀態
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    //呼叫執行緒的中斷方法
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
複製程式碼

相關文章