当前位置: 首页 > news >正文

广州网站开发设计新闻资讯网站模板

广州网站开发设计,新闻资讯网站模板,wordpress 哪个版本,企业网站页面宽哪里设置文章目录一、处理异步任务并获取返回值——CompletionService二、线程池三、Callable 与 Future四、通过回调方式处理可组合编排任务——CompletableFuture一、处理异步任务并获取返回值——CompletionService 特点描述: 对于比较复杂的计算,把…

文章目录

      • 一、处理异步任务并获取返回值——CompletionService
      • 二、线程池
      • 三、Callable 与 Future
      • 四、通过回调方式处理可组合编排任务——CompletableFuture

一、处理异步任务并获取返回值——CompletionService

特点描述:
        对于比较复杂的计算,把任务进行提交,并发执行,哪个任务先执行完,get()方法就会获取到相应的任务结果。

范式:
1、
        假设有一组针对某个问题的任务solvers(需要实现Callable接口,任务的具体逻辑就在其call方法里),每个任务都返回一个类型为Result的值,并且想要并发地运行它们,处理每个返回一个非空值的结果,在某些方法使用:

void solve(Executor e,Collection<Callable<Result>> solvers)throws InterruptedException, ExecutionException {CompletionService<Result> ecs= new ExecutorCompletionService<Result>(e);for (Callable<Result> s : solvers)ecs.submit(s);int n = solvers.size();for (int i = 0; i < n; ++i) {Result r = ecs.take().get();if (r != null)use(r);}}

2、
        假设想使用任务集的第一个非空结果,忽略任何遇到异常的任务,并在第一个任务准备好时取消所有其他任务(比如:多仓库文件/镜像下载,从最近的服务中心下载后,终止其他下载过程)

void solve(Executor e,Collection<Callable<Result>> solvers)throws InterruptedException {CompletionService<Result> ecs= new ExecutorCompletionService<Result>(e);int n = solvers.size();List<Future<Result>> futures= new ArrayList<Future<Result>>(n);Result result = null;try {for (Callable<Result> s : solvers)futures.add(ecs.submit(s));for (int i = 0; i < n; ++i) {try {Result r = ecs.take().get();if (r != null) {result = r;break;}} catch (ExecutionException ignore) {}}}finally {for (Future<Result> f : futures)// 注意这里的参数给的是 true,详解同样在前序 Future 源码分析文章中f.cancel(true);}if (result != null)use(result);}

总得来说分两步:
1、提交异步任务 submit方法(submit最终会委托给内部的 executor 去执行任务)
2、从队列中拿取并移除元素 take(如果队列为空,那么调用 take() 方法的线程会被阻塞)/poll(…不会被阻塞,返回null)/poll带超时参数(获取并移除阻塞队列中的第一个元素,如果超时时间到而队列还是空,该方法返回null) 方法

实现原理:
        将异步任务的生产、任务完成结果的消费进行解耦,类似mq,哪个任务先执行完,就把结果放到队列中。

唯一实现类:
        ExecutorCompletionService;阻塞队列默认是 LinkedBlockingQueue

二、线程池

为什么要用线程池
        ∵ 手动创建线程的缺点:
1、不受控,系统资源有限,每个人如果都创建的话,标准不一样,线程疯狂抢占资源.,混乱…
2、开销大,创建一个线程需要调用操作系统内核API,然后操作系统要为线程分配一系列资源,创建个线程啥也不干大概需要1M左右大小。

        线程池可以统一管理、控制最大并发数并实现拒绝策略、隔离线程环境;当执行大量异步任务时,线程池里的线程能复用,不用频繁创建和销毁,能够提供好的性能。
       
Java并发包里的线程池——ThreadPoolExecutor; (接口是ExecutorService)
Spring对线程池的封装——ThreadPoolTaskExecutor
       
关于线程池核心线程数的设置:
        CPU是时间片轮转机制来让线程占用的,也就是说程序表面上是同时进行的,实际上是切换执行的,CPU每个时刻只能由一个线程占用,比如 4核CPU,只能同时跑4个线程。
       
对于CPU密集型程序(如运算、逻辑判断等,I/O操作可以在短时间完成,但CPU运算比较多)
——最佳线程数量=CPU核数+1,这个1可以理解为替补,如果某个线程因为发生错误或其他原因暂停了,这个线程可以继续工作。
       
对于I/O密集型(如涉及网络、磁盘、内存等)
——最佳线程数=CPU核心数 * (1/CPU利用率)=CPU核心数 * (1 + (I/O耗时/CPU耗时)),如果几乎都是I/O耗时,可取2N+1(1为替补)
       
(p.s.线程数不是越多越好,线程上下文切换开销不小)
       

三、Callable 与 Future

        Runnable接口的方法没有返回值;Callable 是泛型接口,可以返回指定类型的结果。
        当提交一个Callable 任务后,会同时获得一个Future对象,然后,在主线程某个时刻调用Future对象的get() 方法,就可以获得异步执行的结果。在调用get()时,如果异步任务已经完成,就直接获得结果。如果异步任务还没有完成,那么get()会阻塞,直到任务完成后才返回结果。
       

四、通过回调方式处理可组合编排任务——CompletableFuture

特点描述:
        CompletableFuture是由 Java 8 引入的,在 Java 8之 前一般通过 Future 实现异步,CompletableFuture 对 Future 进行了扩展,可以通过设置回调的方式处理计算结果,同时也支持组合操作,比如步骤1、2、3存在依赖关系,支持对步骤进一步的编排,降低依赖之间的阻塞。

使用:
在这里插入图片描述

        如上图所示,这里描绘的是一个业务接口的流程,其中包括 CF1\CF2\CF3\CF4\CF5 共5个步骤,并描绘了这些步骤之间的依赖关系,每个步骤可以是一次 RPC 调用、一次数据库操作或者是一次本地方法调用等,在使用 CompletableFuture 进行异步化编程时,图中的每个步骤都会产生一个 CompletableFuture 对象,最终结果也会用一个 CompletableFuture 来进行表示。(只看第一层的话 好像跟 CompletionService 效果差不多… 都可以异步执行批量任务并拿到结果…)

1、零依赖,CompletableFuture 的创建
比如图中所示的 CF1、CF2,可以有以下方式:

     // 1、使用 runAsync 或 supplyAsync 发起异步调用// 线程池ExecutorService executorService = Executors.newFixedThreadPool(5);CompletableFuture<String> CF1 = CompletableFuture.supplyAsync(() -> {return "CF1 result";}, executorService);// 2、CompletableFuture.completedFuture() 直接创建一个已完成状态的 CompletableFuture<CompletableFuture<String> CF2 = CompletableFuture.completedFuture("CF2 result");// 3、先初始化一个未完成的 CompletableFutureCompletableFuture<String> CF3 = new CompletableFuture<>();// 然后通过complete()、completeExceptionally(),完成该CompletableFutureCF3.complete("CF3result");

2、一元依赖,依赖一个 CompletableFuture
比如图中所示的 CF3、CF5,可以用 thenApply、thenAccept、thenCompose 等方法来实现:

// result为CF1的结果CompletableFuture<String> CF3=CF1.thenApply(result->{return "CF3result";});

3、二元依赖:依赖两个 CompletableFuture
比如图中所示的 CF4,这种二元依赖可以通过 thenCombine 等回调来实现:

   // result1、result2分别为CF1、CF2的结果CompletableFuture<String> CF4 = CF1.thenCombine(CF2, (result1, result2) -> {return "CF4result";});

4、多元依赖,依赖多个 CompletableFuture
比如图中所示的 CF6,依赖于三个步骤CF3、CF4、CF5,这种多元依赖可以通过 allOf 或 anyOf 方法来实现,区别是当需要多个依赖全部完成时使用allOf,当多个依赖中的任意一个完成即可时使用anyOf:

    CompletableFuture<Void> CF6 = CompletableFuture.allOf(CF3, CF4, CF5);CompletableFuture<String> result = CF6.thenApply(v ->{// 这里的 join是完成任务后用来获取结果的,并不会阻塞// 因为传给 thenApply 的函数都是在 CF3、CF4、CF5 全都完成时才会执行String result3 = CF3.join();String result4 = CF4.join();String result5 = CF5.join();// 根据 result3、result4、result5组装最终 resultreturn result3 + result4 + result5;});

        如果只用一层的话,异步执行批量任务并拿到总的结果,参考api里 allOf:
在这里插入图片描述

代码示例:

 // 任务入参集合ArrayList<String> paramList = new ArrayList<>();// 用于汇总所有结果ArrayList<String> resultList = new ArrayList<>();CompletableFuture.allOf(paramList.stream().map(string ->CompletableFuture.supplyAsync(() ->// 这里返回了本身,实际上也可以是具体的方法string,asyncServiceExecutor)// thenApply是对结果做简单映射,类似于Stream.map,list->list就是原样往下传递,这里不使用thenApply也行.thenApply(list -> list).whenComplete((result, e) -> {// 对异常结果的处理if (e != null) System.out.println("exception");// 汇总结果resultList.add(result);})).toArray(CompletableFuture[]::new)// 完成后返回结果值,如果异常完成则抛出(未经检查)异常,相当于一个等待任务完成的动作).join(); 

参考文档:
https://dayarch.top/p/how-many-threads-should-be-created.html
https://segmentfault.com/a/1190000023129592?utm_source=sf-similar-article
https://segmentfault.com/a/1190000023587881
https://tech.meituan.com/2022/05/12/principles-and-practices-of-completablefuture.html

http://www.yayakq.cn/news/780252/

相关文章:

  • 网站开发属于哪个税收分类装修做劳务去哪个网站找工地
  • 河北建设网站怎么下载企业锁汕头网站建设维护
  • 微官网和移动网站区别百家利网站开发
  • c# asp.net网站开发书wordpress用的php
  • 做购物平台网站需要注意什么广东省建筑施工企业安全管理人员
  • 网站链接视频怎么做温州网站建设结构
  • 公益组织网站源码潍坊知名网站建设怎么收费
  • 明空网络做网站好不好wordpress邮箱验证失败
  • 湘西建设监理协会网站wordpress主题怎么做
  • 福建省住房和城乡建设局网站让wordpress 文章 id重新排列
  • 南京公司网站建设房地产网站制作
  • 网站上传视频教程wordpress 交互页面
  • 域名数和网站数windows建立网站
  • 防做网站视频网站备案 法人变更
  • 网站不备案有什么影响专业购物网站建设报价
  • 苏州网站建设布局企业法人手机号码查询
  • 佛山网站建设企业开源 企业网站
  • 如何做好网站的优化的监测评价浪漫做爰网站
  • 美术设计网站优化需要什么软件
  • 重庆网站制作招聘千库网ppt模板免费
  • 贵州省住房和城乡建设厅网网站北京信息网招聘最新
  • 34线城市做网站推广在线电子书网站怎么做
  • 常州城乡和住房建设厅网站长沙建站模板
  • 昆明建站网站资讯平台黄冈论坛东湖社区
  • 网站制作报价单模板狗和女主人做爰网站
  • 注册网站电子游戏送钱了38网上怎么卖东西
  • seo网站描述之间用什么标点符号大学生创新创业大赛的意义
  • 多大的服务器可以做视频网站最新新闻热点事件100字
  • wordpress 大学网站中国建设银行绑定网站
  • 网站的网页建设知识ppt网页浏览器英文缩写