通常,当我们开发一个简单的并发应用时,会创建Runnable对象,用Thread对象来运行,但如果要一个程序由大量的并发任务
这个方法就会有以下劣势1.必须实现所有与Thread对象管理相关的代码
2.需要为每个任务创建一个Thread对象
3,。如果创建过多线程,导致系统负荷过重
自java5以后,java提供了执行器框架(Executor Framework)来解决这些问题
该框架的重要优势是Callable接口,类似于Runnable接口
1.接口住方法为call(),可以有返回结果,替换了Runnable中的run()方法
2.当发送一个Callable对象给执行器时,将获得一个Future接口对象,可以使用它来控制Callable对象的状态和结果。
一.创建执行器
1.使用ExecutorService 接口
ExecutorService pool = Executors.newFixedThreadPool(3);
Thread t1 = new MyThreaed();
pool.execute(t1);
2.使用ThreadPoolExecutor实现类
ThreadPoolExecutor pool = (ThreadPoolExecutor)Executors.newcachedThreadPool();
Thread t1 = new MyThreaed();
pool .execute(t1);
建议:.不要使用ThreadPoolExecutor的构造方法来创建对象,利用工厂模式Executors来创建ThreadPoolExecutor对象
工厂模式中有以下几种可以创建,1.创建固定大小的线程执行器 Executors.newFixedThreadPool(5)
2.创建缓存线程池,到达线程重用目的,如果超过默认线程,系统负荷会过载 Executors.newcachedThreadPool()
3.创建只有一个线程的执行器Executors.newSingleThreadExecutor()
.....
二 在执行器中执行任务并返回
public classs Calculator implements Callable<Integer>{
@Override
public Integer call(){return 1;}
}
public class Main{
public void main(String[] args){
ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(2);
Calculator ca = new Calcullator();
//存储返回值
Future<Integer> result = executor.submit(ca);
//关闭执行器
executor .shutdown();
}
}
三、运行多个任务并处理第一个结果
在并发编程中,当使用多个并发任务来解决一个问题的时候,往往只关心这些任务中的第一个结果
只需要
result = executor.invokeAny(taskList);//通过执行器执行一个任务列表taskLIst,
运行多个任务并处理所有结果
resultList = executor.invokeAll(taskList);
四、延时执行任务 ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)Executors.newScheduledThreadPoolExecutor(1);
executor.schedule(task,1,TimeUnit.SECONDS);//第二三个参数,分别延时的时间和时间单位
五、周期性执行任务
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)Executors.newScheduledThreadPoolExecutor(1);
ScheduledFuture<?> result = executor.scheduleAtFixedRate(task,1,2,TimeUnit.SECONDS);
六、在执行器中取消任务
//调用submit将任务发送给执行器
Future<String> result = executor.submit(task);
result.cancel(true);
七、在执行器中控制任务的完成,方式:继承FutureTask方法,覆盖done方法,在线程任务执行完的时候会调用该方法
public class ResultTask extends FutureTask(){
@Override
publci void done(){}
}
八、处理在执行器中被拒绝的任务
如果在执行执行器执行shutdown()之后,还想让它再执行线程,会被拒绝,通过实现RejectExceptionHandler接口实现
public class RejectedTaskController implements RejectExceptionHandler{
@Override
public void rejectedExecution(Runnable r,ThreadPoolExecutor executor){
//自定义异常操作
}
}
main:
RejectedTaskController controller = new RejectedTaskController ();
ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(2);
executor.setRejectExceptionHandler(controller );