2013-11-09 62 views
3

我正在查看ThreadPoolExecutor類,我發現它允許指定最大池大小和核心池大小。什麼是ThreadPoolExecutor的核心線程?

我明白了,一點點,什麼時候改變基於此答案的核心和最大池大小:When is specifying separate core and maximum pool sizes in ThreadPoolExecutor a good idea?

不過,我想知道這些是什麼「芯線」。我總是得到0,當我使用這裏ThreadPoolExecutor

SSCCE的getCorePoolSize()方法:

import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 
import java.util.concurrent.ThreadPoolExecutor; 

public class PoolSize { 
    public static void main(String[] args) { 
     // Create a cached thread pool 
     ExecutorService cachedPool = Executors.newCachedThreadPool(); 
     // Cast the object to its class type 
     ThreadPoolExecutor pool = (ThreadPoolExecutor) cachedPool; 

     // Create a Callable object of anonymous class 
     Callable<String> aCallable = new Callable<String>(){ 
      String result = "Callable done !"; 
      @Override 
      public String call() throws Exception { 
       // Print a value 
       System.out.println("Callable at work !"); 
       // Sleep for 5 sec 
       Thread.sleep(0); 
       return result; 
      } 
     }; 

     // Create a Runnable object of anonymous class 
     Runnable aRunnable = new Runnable(){ 
      @Override 
      public void run() { 
       try { 
        // Print a value 
        System.out.println("Runnable at work !"); 
        // Sleep for 5 sec 
        Thread.sleep(0); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }; 

     // Submit the two tasks for execution 
     Future<String> callableFuture = cachedPool.submit(aCallable); 
     Future<?> runnableFuture = cachedPool.submit(aRunnable); 

     System.out.println("Core threads: " + pool.getCorePoolSize()); 
     System.out.println("Largest number of simultaneous executions: " 
              + pool.getLargestPoolSize()); 
     System.out.println("Maximum number of allowed threads: " 
              + pool.getMaximumPoolSize()); 
     System.out.println("Current threads in the pool: " 
              + pool.getPoolSize()); 
     System.out.println("Currently executing threads: " 
              + pool.getTaskCount()); 

     pool.shutdown(); // shut down 

    } 
} 

回答

5

核心線程是以防萬一你想傳遞一個任務,始終運行在最低限度。正如您所預料的那樣,默認情況下,緩存池的內核爲0

對於固定線程池,核心和最大值是相同的,即無論您設置固定大小。

+0

好的,如果在「緩存線程池」中,我改變了核心線程的數量,然後類似於「固定線程池」,這些人將永遠在那裏。但是,未使用超過一分鐘的線程將被丟棄。淨結果是結合了緩存和固定線程池的好處。對 ? –

+0

您最終創建了一個只有少量線程的池,這些線程始終處於待機狀態,並根據需要創建其他線程。空閒線程不會佔用內存,因爲它們所佔用的資源將被釋放。 –

0

core threads只是標準的線程,但將在池中始終保持活躍,然後將其他非核心線程將結束自己的生命的run()方法完成之後。

但是這些core threads怎麼會一直活着?這是因爲他們一直在等待從池中共享的workQueue中獲取任務。默認情況下,workQueueBlockingQueue,其方法take()將無限期地阻塞當前線程,直到任務變爲可用。

這裏的關鍵點是,哪些線程將成爲core threads?它們可能不是第一個或最後一個,而是持續時間最長的那個(corePoolSize)。從代碼更容易理解。

private Runnable getTask() { 
 
     boolean timedOut = false; // Did the last poll() time out? 
 

 
     for (;;) { 
 
      int c = ctl.get(); 
 
      int rs = runStateOf(c); 
 

 
      // Check if queue empty only if necessary. 
 
      if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) { 
 
       decrementWorkerCount(); 
 
       return null; 
 
      } 
 

 
      int wc = workerCountOf(c); 
 

 
      //------------- key code ------------------ 
 
      // Are workers subject to culling? 
 
      boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; 
 

 
      if ((wc > maximumPoolSize || (timed && timedOut)) 
 
       && (wc > 1 || workQueue.isEmpty())) { 
 
       if (compareAndDecrementWorkerCount(c)) 
 
        return null; 
 
       continue; 
 
      } 
 

 
      //------------- key code ------------------ 
 
      try { 
 
       Runnable r = timed ? 
 
        workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : 
 
        workQueue.take(); 
 
       if (r != null) 
 
        return r; 
 
       timedOut = true; 
 
      } catch (InterruptedException retry) { 
 
       timedOut = false; 
 
      } 
 
     } 
 
    }

我剛纔上面說的是基於allowCoreThreadTimeOut設置爲false

其實,我更願意撥打core threads作爲core workers

相關問題