`
yaozhiqiang109
  • 浏览: 117549 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

多线程 (2) ThreadPoolExecutor 介绍和 FutureTask使用

    博客分类:
  • JAVA
阅读更多

FutureTask是一种可以取消的异步的计算任务。它的计算是通过Callable实现的,并且有三个状态:等待、运行和完成。完成包括所有计算以任意的方式结束,包括正常结束、取消和异常。

 

 

V 	get()
          如有必要,等待计算完成,然后检索其结果。
 V 	get(long timeout, TimeUnit unit)
          如有必要,最多等待为使计算完成所给定的时间之后,检索其结果(如果结果可用)。
 

Executor框架利用FutureTask来完成异步任务,并可以用来进行任何潜在的耗时的计算。一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。

 

 

public class TestFutureTask {

    /**
     * @param args
     * @create_time 2011-6-24 下午03:41:57 
     */
    public static void main(String[] args) {
        //创建线程池
        ThreadPoolExecutor pool=new ThreadPoolExecutor(3,3,2,TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(10),new ThreadPoolExecutor.AbortPolicy());
        List<FutureTask<String>>  tasks=new ArrayList<FutureTask<String>>();
        for(int i=0;i<10;i++){
            FutureTask<String> futureTask=new FutureTask<String>(new ThreadPoolTask(i));
            pool.submit(futureTask);
            tasks.add(futureTask);
        }
        for (FutureTask<String> futureTask : tasks) {
            try {
                //阻塞一直等待执行完成拿到结果
                System.out.println("future result:"+futureTask.get());
                //阻塞一直等待执行完成拿到结果,如果在超时时间内,没有拿到则抛出异常
//                System.out.println("future result:"+futureTask.get(1,TimeUnit.SECONDS));
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } //捕获超时异常
//            catch (TimeoutException e) {
//                e.printStackTrace();
//            }
        }
    }
    /**
     * 执行业务计算
     * 
     * @date 2011-6-24
     * Copyright (C) 2010-2012 www.2caipiao.com Inc. All rights reserved.
     */
    public static class ThreadPoolTask implements Callable<String>{

        private int value;
        
        public ThreadPoolTask(int value){
            this.value=value;
        }
        @Override
        public String call() throws Exception {
            //计算
            System.out.println("value-----"+value++);
            Thread.sleep(2000);
            return String.valueOf(value);
        }
        
    }
}
 

 

线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:

 

 

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
 
 
corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略
 

 

 

 

当一个任务通过execute(Runnable)方法欲添加到线程池时:
 
  如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
  如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
  如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
  如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
  当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
 
unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、
MICROSECONDS、
MILLISECONDS、
SECONDS。
 

 

 

workQueue常用的是:java.util.concurrent.ArrayBlockingQueue
 
handler有四个选择:
ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
 
ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
 
ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
 
ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
 

 


1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics