Liny_@NotePad

沉迷ACG中

ThreadPoolExecutor的使用

YOYO posted @ 2009年4月15日 23:17 in 【Java SE】 with tags ThreadPoolExecutor 多线程 , 4125 阅读

一个 ExecutorService,它使用可能的几个池线程之一执行每个提交的任务,通常使用 Executors 工厂方法配置。
线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行集合任务时使用的线程)的方法。每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。

下面是一个简单的例子,详细用法大家还是要查下API……

[ThreadPoolExecutorDemo]
创建了一个队列用于存放数据(整型)和一个线程池,
一开始填满队列,并启动5个线程来执行任务。

  1. import java.util.concurrent.*;
  2.  
  3. public class ThreadPoolExecutorDemo {
  4.  
  5.         static BlockingQueue<Integer> warehouse = new ArrayBlockingQueue<Integer>(100);
  6.        
  7.         static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(  10,       //     核心线程数:池中所保存的线程数,包括空闲线程
  8.                                                                                                                                         20,     //   池中允许的最大线程数
  9.                                                                                                                                         1,      //    当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间
  10.                                                                                                                                         TimeUnit.SECONDS,       //     keepAliveTime 参数的时间单位 
  11.                                                                                                                                         new LinkedBlockingQueue(20)
  12.                                                                                                                         //      执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。
  13.         );
  14.        
  15.         public static void main(String[] args){
  16.                 //      预备数据:填满整个队列
  17.                 for(int i=0; warehouse.remainingCapacity()>0; i++){
  18.                         warehouse.offer(i);
  19.                 }
  20.                
  21.                 //      线程池执行:
  22.                 for(int i=0; i<5; i++){
  23.                         threadPool.execute(new PrintIntThread(warehouse));
  24.                 }
  25.                
  26.                 //      令这些任务都执行完后关闭线程池
  27.                 threadPool.shutdown();
  28.         }
  29.        
  30. }

 

[PrintIntThread]
该类实现了Runnable接口,目的是处理任务。
当数据未取完时一直取数据。(这里为了观察方便,定义每次取完后休息一段时间)

  1. import java.util.concurrent.BlockingQueue;
  2.  
  3.  
  4. public class PrintIntThread implements Runnable {
  5.  
  6.         static BlockingQueue<Integer> warehouse;
  7.        
  8.         public PrintIntThread(BlockingQueue<Integer> warehouse) {
  9.                 this.warehouse = warehouse;
  10.         }
  11.  
  12.         public void run() {
  13.                 while(warehouse.size()>0){
  14.                         try {
  15.                                 System.out.println(Thread.currentThread().getName() + " 取出了" + warehouse.take());
  16.                                 Thread.sleep((int) (Math.random() * 300));      //    为便于观察 随机等待300ms内的时间
  17.                         } catch (InterruptedException e) {
  18.                                 e.printStackTrace();
  19.                         }
  20.                 }
  21.         }
  22.  
  23. }

* 注意
· 线程池要记得关闭,若没有shutdown则应用程序不会停止……
· 若启动的线程小于核心线程数,则线程池会自动创建新线程,即使空闲着。
· 若当前线程数大于核心线程数,当一个线程空闲时间超过定义的时间时线程池会自动终止该线程。
· 每次提交任务,线程池分配给空闲线程,若没有则存放到任务队列中,队列已满时线程池才创建新线程去处理任务(按需构造),但若当前线程数已达到线程池最大应许线程数时则任务会被拒绝。任务队列有好几种,大家自己看API……


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter