2017-02-12 86 views
1

我知道一些關於AbstractQueuedSynchronizer的細節。 它是用於創建狀態相關類或同步器的框架。 但我沒有得到在ThreadPoolExecutor的Worker中擴展這個類的要點。

private final class Worker extends AbstractQueuedSynchronizer implements Runnable 

所看到下面的東西Worker類的簽名可以推斷:

  1. 當一個新的Runnable /贖回的任務提交後,會創建一個新的工作對象。

  2. Worker的新對象可被視爲新線程。

  3. addWorker()方法將添加新工作人員(或簡單地任務)並調用本身worker.start()來啓動線程。

  4. Worker類是非靜態的嵌套類,因此它可以訪問(本)

    公共無效的run()的ThreadPoolExecutor

    的所有變量Worker類的
  5. run()方法內部調用runWorker { runWorker (這個); }

  6. runWorker()執行實際任務是這樣的:

    void runWorker(Worker w) { try { w.lock(); w.firstTask.run() } finally { w.unlock(); } }

AQS只用於此鎖和runWorker()方法解鎖。 難道我們不能在這裏使用ReentrantLock並保持Worker類簡單嗎?

而且類提供有關本文檔,但我無法理解的是:

此類投機擴展的AbstractQueuedSynchronizer到 簡化獲取和釋放圍繞每個任務 執行的鎖。這可以防止意圖喚醒等待任務的工作線程的中斷,而不是中斷正在運行的任務 。我們實現了一個簡單的非重入互斥鎖 ,而不是使用ReentrantLock,因爲我們不希望工作任務到 能夠在調用像setCorePoolSize這樣的池控制方法 時重新獲取鎖。

請幫上你的問題

回答

2

答案是引自javadoc,你的貼:

我們實現一個簡單的非再進入的互斥鎖,而不是 使用ReentrantLock的,因爲我們做的不希望工作任務能夠在 調用池控制方法(如 setCorePoolSize)時重新獲取鎖。

這是因爲線程可能會等待任務由沒有被鎖定表示,即tryLock回報true他們。並可能在這種情況下會發生什麼,如果ReentrantLock將在這裏使用:那麼這將是可能的行動順序如下:(!在這裏成功)

setCorePoolSize - - >interruptIdleWorkers>tryLock() - >Thread.interrupt(這名工人的線程)

這將導致工人中斷本身。