2013-11-09 61 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

相关问题