首页 > 编程知识 正文

completion rate,completablefuture 线程池

时间:2023-05-06 14:19:14 阅读:51000 作者:3317

1. ExecutorService中的submit ()和execute ) )的差异execute只能提交Runnable类型的任务,没有返回值。 提交既可以提交Runnable类型的任务,也可以提交Callable类型的任务。 有Future类型的返回值,但如果任务类型为Runnable,则返回值为null。 submit ) )可以执行Exception处理。 执行任务时,execute在发生异常时直接抛出,但submit不直接抛出,而是在成员变量中保存异常,并在FutureTask.get被阻止检索时抛出异常。 参考:并发编程的提交和执行的区别(七)

2 .完成服务和执行完成服务实现目标为任务先完成可优先获取到,即结果按照完成先后顺序排序。

/**一*1.在list中收集任务结果(list记录每个submit返回的Future )2.循环查看结果,Future不一定完成。 如果没有完成,调用get就借插件)3.如果前面排列的任务没有完成,就会被阻止。 这样,后来完成的任务就得不到结果。 导致了不必要的等待时间。 *更严重的是,的第一个任务几个小时或永远不会完成,之后的任务几秒钟就结束了,之后的任务结果没有得到处理* *结果,完成的任务是*/privatestaticvoidcase1(throwsexecase1) interrupted exception { final random }可能不会立即处理executorserviceservice=executors.newfixedthreadpool (10; listfuturestringtaskresultholder=new ArrayList (; for(intI=0; i50; I )//收集任务结果的taskresultholder.add (service.submit (newcallablestring ) ) { public string call } (throws exception ) ) () ); //处理任务结果int count=0; system.out.println (handleresultbegin ); for (futurestringfuture : taskresultholder (system.out.println ) future.get ) ); 出局; } system.out.println (handleresultend ); system.out.println (count ' task done!' ); //线程池service.shutdown (; }对第一种情况的改进:

/** 2二是改善第一种情况。 1 .检查任务是否已完成,如果已完成,则检索任务结果,并从后面的任务列表中删除任务。 *2.如果任务未完成,请跳过此任务,继续检查以下任务的结果: * 3.如果到达任务列表的末尾,则返回任务列表后开始。 然后,从第一步开始* *现在您可以立即处理已完成任务的结果。 * /私有静态语音情况2 ) throws ExecutionException,interrupted exception (finalrandomrandom=)。 executorserviceservice=executors.newfixedthreadpool (10; listfuturestringresults=new ArrayList (; for(intI=0; i50; I ) { CallableString

gt; task = new Callable<String>() { public String call() throws Exception { Thread.sleep(random.nextInt(5000)); //模拟耗时操作 return Thread.currentThread().getName(); } }; Future<String> future = service.submit(task); results.add(future); // 搜集任务结果 } int count = 0; //自旋, 获取结果 System.out.println("handle result begin"); for(int i=0; i<results.size(); i++) { Future<String> taskHolder = results.get(i); if(taskHolder.isDone()) { //任务完成 String result = taskHolder.get(); //获取结果, 进行某些操作 System.out.println("result: " + result); results.remove(taskHolder); i--; count++; //完成的任务的计数器 } //回到列表开头, 从新获取结果 if(i == results.size() - 1) i = -1; } System.out.println("handle result end"); System.out.println(count + " task done !"); //线程池使用完必须关闭 service.shutdown(); }

使用ExecutorCompletionService管理异步任务:

/** * <三> 使用ExecutorCompletionService管理异步任务 * 1. Java中的ExecutorCompletionService<V>本身有管理任务队列的功能 * i. ExecutorCompletionService内部维护列一个队列, 用于管理已完成的任务 * ii. 内部还维护列一个Executor, 可以执行任务 * * 2. ExecutorCompletionService内部维护了一个BlockingQueue, 只有完成的任务才被加入到队列中 * * 3. 任务一完成就加入到内置管理队列中, 如果队列中的数据为空时, 调用take()就会阻塞 (等待任务完成) * i. 关于完成任务是如何加入到完成队列中的, 请参考ExecutorCompletionService的内部类QueueingFuture的done()方法 * * 4. ExecutorCompletionService的take/poll方法是对BlockingQueue对应的方法的封装, 关于BlockingQueue的take/poll方法: * i. take()方法, 如果队列中有数据, 就返回数据, 否则就一直阻塞; * ii. poll()方法: 如果有值就返回, 否则返回null * iii. poll(long timeout, TimeUnit unit)方法: 如果有值就返回, 否则等待指定的时间; 如果时间到了如果有值, 就返回值, 否则返回null * * 解决了已完成任务得不到及时处理的问题 */ static void case3() throws InterruptedException, ExecutionException { Random random = new Random(); ExecutorService service = Executors.newFixedThreadPool(10); ExecutorCompletionService<String> completionService = new ExecutorCompletionService<String>(service); for(int i=0; i<50; i++) { completionService.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(random.nextInt(5000)); return Thread.currentThread().getName(); } }); } int completionTask = 0; while(completionTask < 50) { //如果完成队列中没有数据, 则阻塞; 否则返回队列中的数据 Future<String> resultHolder = completionService.take(); System.out.println("result: " + resultHolder.get()); completionTask++; } System.out.println(completionTask + " task done !"); //ExecutorService使用完一定要关闭 (回收资源, 否则系统资源耗尽! .... 呵呵...) service.shutdown(); }}

参考:CompletionService和ExecutorCompletionService详解

3. Future vs CompletableFuture

CompletableFuture:Future的增强版

CompletableFuture实现了Future接口,既可以完成Future所有能做的事。最关键是,它还实现了CompletionStage接口,该接口描述了一个异步计算的阶段。很多计算可以分成多个阶段或步骤,此时可以通过它将所有步骤组合起来,形成异步计算的流水线。

参考:Java并发编程系列一:Future和CompletableFuture解析与使用

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。