Java 8中的并行和异步编程

并行代码是在多个线程上运行的代码,曾经是许多经验丰富的开发人员的噩梦,但是Java 8带来了许多更改,这些更改应该使这种提高性能的技巧更加易于管理。

并行流

在Java 8之前,并行(或并发)代码与顺序代码之间存在很大差异。 调试非顺序代码也非常困难。 只需像通常那样设置一个断点并按照流程进行操作,就可以删除并行方面,如果这是导致该错误的原因,那么这是一个问题。

幸运的是,Java 8为我们提供了流,这是自Bean以来对Java开发人员而言最大的事情。 如果您不知道它们是什么,则Stream API可以处理功能问题中的元素序列。 (在这里检查流与.NET的LINQ之间的比较。)流的优点之一是代码的结构保持不变:无论是顺序的还是并发的,它都保持可读性。

为了使您的代码并行运行,您只需使用.parallelStream()而不是.stream() (或者,如果您不是流的创建者,则可以使用stream .parallel() )。

但是,仅仅因为它很容易,并不意味着并行代码始终是最佳选择。 您应该始终考虑对代码使用并发是否有意义。 该决定中最重要的因素将是速度:仅当并发使您的代码比其顺序对应的代码更快时才使用并发。

速度问题

并行代码通过使用多个线程而不是顺序代码使用的单个线程而获得了速度优势。 确定创建多少个线程可能是一个棘手的问题,因为更多的线程并不总是会导致更快的代码:如果使用太多的线程,则代码的性能实际上可能会下降。

有几个规则可以告诉您选择多少线程。 这主要取决于您要执行的操作类型以及可用内核的数量。

计算密集型操作应使用少于或等于内核数的线程数,而IO密集型操作(如复制文件)对CPU无用,因此可以使用更多线程。 该代码不知道哪种情况适用,除非您告诉它该怎么做。 否则,它将默认为线程数等于内核数。

在两种主要情况下,并行运行代码而不是顺序运行代码很有用:耗时的任务和在大集合上运行的任务。 Java 8带来了一种处理大集合的新方法,即使用流。 流具有惰性的内置效率:它们使用惰性评估,通过不做不必要的事情来节省资源。 这与并行性不同,只要它运行得更快,它就不会在乎资源。 因此,对于大型集合,您可能不需要经典的并行性。

================================================== ====================

异步

JavaScript的教训

Java开发人员很少会说他们从看过JavaScript中学到了什么,但是在异步编程方面,JavaScript实际上是正确的。 作为一种从根本上异步的语言,JavaScript经验丰富,如果实施不好,它会带来多大的痛苦。 它从回调开始,后来被promise取代。 许诺的一个重要好处是它有两个“通道”:一个用于数据,另一个用于错误。 JavaScript承诺可能看起来像这样:

func
.then(f1)
.catch(e1)
.then(f2)
.catch(e2);

因此,当原始函数获得成功结果时,将调用f1,但是如果引发错误,则将调用e1。 这可能会将其带回到成功轨道(f2),或导致另一个错误(e2)。 您可以从数据跟踪到错误跟踪再返回。

JavaScript承诺的Java版本称为CompletableFuture 。

未来发展

CompletableFuture同时实现FutureCompletionStage接口。 Java8之前就已经存在Future ,但是它本身对开发人员并不十分友好。 您只能使用.get()方法获得异步计算的结果,该方法会阻塞其余部分(使异步部分大部分时间变得毫无意义),并且您需要手动实现每种情况。 添加CompletionStage接口是使Java异步编程可行的突破。

CompletionStage是一个承诺,即最终将完成计算的承诺。 它包含许多方法,可让您附加将在完成时执行的回调。 现在我们可以处理结果而不会阻塞。

有两种主要方法可让您启动代码的异步部分: supplyAsync如果您想对方法的结果做一些事情)和runAsync如果您不想这样做)。

CompletableFuture.runAsync(() → System.out.println("Run async in completable future " + Thread.currentThread()));
CompletableFuture.supplyAsync(() → 5);

回呼

现在,您可以添加这些回调以处理supplyAsync的结果

CompletableFuture.supplyAsync(() → 5)
.thenApply(i → i * 3)
.thenAccept(i → System.out.println(“The result is “ + i)
.thenRun(() → System.out.println("Finished."));

.thenApply.thenApply.map函数相似:它执行转换。 在上面的示例中,它将结果(5)乘以3。然后将结果(15)进一步传递给管道。

.thenAccept对结果执行一种方法,而无需对其进行转换。 它也不会返回结果。 它将在控制台上显示“结果为15”。 可以将它与.foreach方法进行流比较。

.thenRun不使用异步操作的结果,也不返回任何内容,它只是等待调用其Runnable直到上一步完成为止。

异步处理

上述所有回调方法也都具有异步版本: thenRunAsyncthenApplyAsync等。这些版本可以在自己的线程上运行,它们为您提供了额外的控制权,因为您可以告诉它要使用哪个ForkJoinPool

如果您不使用异步版本,则所有回调将在同一线程上执行。

当事情出错时

当出现问题时,将使用exceptionally方法来处理异常。 您可以给它提供一个方法,该方法返回一个值以返回数据轨道,或引发(新)异常。

…
.exceptionally(ex → new Foo())
.thenAccept(this::bar);

合并和撰写

您可以使用thenCompose方法链接多个CompletableFutures 。 没有它,结果将嵌套CompletableFutures 。 这使得thenComposethenApplyflatMapmap用于流。

CompletableFuture.supplyAsync(() -> "Hello")
.thenCompose(s -> CompletableFuture
.supplyAsync(() -> s + "World"));

如果要合并两个CompletableFutures的结果,则需要一个方便地称为thenCombine的方法。

future.thenCombine(future2, Integer::sum)
.thenAccept(value →  System.out.println(value));

如您在上面的示例中看到的那样,可以使用所有喜欢的CompletionStage方法像普通的CompletableFuture一样处理thenCombine中的回调结果。

结论

在寻求更快的代码时,并行编程不再是不可克服的障碍。 Java 8使该过程尽可能简单明了,因此,可能从中受益的任何代码都可以在所有线程上被拉,踢和尖叫,进入多核未来,而实际上,这只是现在天。 我的意思是:这很容易做到,因此请尝试一下,看看自己的优势。

翻译自: https://www.javacodegeeks.com/2018/04/parallel-and-asynchronous-programming-in-java-8.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346632.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux微信运行错误,Ubuntu 16.04 运行微信开发者工具编译出错的解决办法

最近有折腾小程序的意向,但微信的开发者工具只提供了 Windows 和 Mac 两个版本,对于我这样的 Linux 用户来说不是那么地友好。经过观察发现,那个开发者工具实际上是基于nw.js开发的,天然地具有跨平台的属性,搜索Github…

springboot security 权限校验_springboot借助aop和注解实现权限校验

我们用springboot做后台开发,难免会用到权限校验,比如查看当前用户是否合法,是否是管理员。而spring的面向切面的特效可以帮助我们很好的实现动态的权限校验。这里我们就用到的spring的aop。接下来就带领大家用aop和注解来快速的实现权限校验…

linux 应用网络连接失败的原因,PuTTY网络错误:软件导致连接中止

解决PuTTY网络错误Software caused connection abort阅读有关该错误的PuTTY怎么说这是Windows网络代码由于某种原因而终止已建立的连接时所产生的一般错误。例如,如果将网络电缆从连接以太网的计算机背面拔出,或者Windows出于其他类似原因认为整个网络都…

javaone_替代JavaOne 2013

javaone我对无法参加JavaOne 2013感到很失望,但是很高兴看到涵盖这个年度会议的大量有用帖子。 在这篇文章中,我链接到许多此类资源,并提供了每篇文章相对于JavaOne 2013讨论内容的简短摘要。 主题演讲 主题演讲是“大公告”趋向于发生的地方…

electron sqlite3_electron集成sqlite3,win10上折腾了2天

要看解决办法的,直接把文章滚动到最后就行了,很简单。最近要做个 IM,PC 端选择用 electron,跨端的最佳选择了。桌面端项目,肯定少不了本地数据库,本来想用 sql.js,看了下需要手动拼接 SQL 语句&…

linux下客户端与ntp同步时间,如何在Windows客户端和Linux NTP服务器之间同步时间?...

我希望我的Windows 7机器能够从我的Linux Debian Sid服务器中获取时间.所以我想提前并从Debian存储库安装OpenNTPD.默认情况下它不会监听任何内容,因此我将其配置如下:listen on 192.168.0.1server 0.debian.pool.ntp.orgserver 1.debian.pool.ntp.orgserver 2.debi…

Java的最新发展– 2018年4月下旬

本周Java领域有一些最新的发展,我在本文中总结了其中的一些。 我们知道的JavaOne的终结 Stephen Chin在帖子“ JavaOne活动扩展了更多的曲目,语言和社区以及新名称 ”中说,“ JavaOne会议正在扩展以创建一个新的更大的活动,该活动…

arrays中copyof复制两个数组_C语言100题集合026-使用指针交换两个数组中的最大值

系列文章《C语言经典100例》持续创作中,欢迎大家的关注和支持。喜欢的同学记得点赞、转发、收藏哦~后续C语言经典100例将会以pdf和代码的形式发放到公众号欢迎关注:计算广告生态 即时查收1 题目函数:max()、swap()功能&#xff1a…

linux 嵌入式串口通信设计目的,基于linux的嵌入式串口通信.doc

PAGE天津电子信息职业技术学院《嵌入式软件编程》课程报告课程名称:基于linux的嵌入式串口通信课程代码: 115229姓 名: 甘琦学 号: 48专 业: 物联网应用技术班 级: 物联S14-1完成时间:2016 年 1…

红头文件rgb红色值_拿下抖音小姐姐,我写了个口红色号识别器

对于广大“钢铁直男”的程序员来说,送什么礼物给女朋友一直是个世纪难题。其实哄女朋友开心最深的套路就是花式送口红,就问谁抵挡得住啊啊啊啊......“没有什么问题是一支口红解决不了的,如果有,那就两支。”于是,直男…

zabbix监控suse linux,SuSE 系统之部署 Zabbix 监控服务

SuSE 系统之部署 Zabbix 监控服务2.4 安装 Apache2 httpd-2.4.2.tar.gz#tar?-zvxf?httpd-2.4.2.tar.gz??#./configure?--prefix/usr/local/services/apache2?--with-apr/usr/local/services/apr/?--with-apr-util/usr/local/services/apr-util/?--with-pcre/usr/local/…

java反射教程_Java反射教程

java反射教程在本教程中,我主要编写一些示例来介绍Java反射可以做什么。 希望它可以给您这个概念的概述。 请留下您的评论以寻求建议。 什么是反射? 简而言之,反射是程序在运行时检查和修改对象的结构和行为的能力。 这个概念有时与内省混合…

腾讯offer是什么样子_月薪35K:2020腾讯Java后端开发详细面试流程

背景2017年我毕业于某不知名二本院校,校招进入一安防企业; 从事于后台服务接入工作。期间一直不断的提高自己,终于在今年如愿以偿,获得腾讯后台开发岗位offer。因此想借此分享成长路上的思考与困难,以及腾讯面试的整个流程。同时在…

Spring Cloud简介–配置(第一部分)

1.概述 Spring Cloud为开发人员提供了工具,以快速构建分布式系统中的某些常见模式(例如,配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局…

Linux 实现网页劫持,Linux下实现劫持系统调用的总结(上)--代码及实现

godbach2015-04-07 19:03yzh07137:你好,我看了你的这篇关于linux劫持open调用的文章[url]http://bbs.chinaunix.net/thread-1946913-1-1.html[/url](有点久远了)我在ubuntu12.04.5(内核是3.13.0.20-32-generic)上试验了,结果编译报错了&#…

python下载之后无法启动_安装后启动时,适用于Python的Eric IDE崩溃

On Windows 7 I successfully installed Python 3.73 and then installed Eric 6, the Python IDE. 安装似乎已成功,但是当我启动Eric时,将打开一个窗口,然后出现错误弹出窗口,提示Python已停止。 我非常感谢您为解决此问题提供的…

深度linux更新卡,深度操作系统已发布更新 新增“ apt-get custom-update”命令行

深度操作系统现已发布最新更新,新增“apt-getcustom-update”命令行,支持指定源更新,同时修复了关闭检查应用商店的应用更新后不生效的问题。此外,使用快捷键“ctrlaltR”进行录屏实际触发为截图的问题也已修复。值得一提的是&…

苹果笔记本macbook pro如何安装python_在Mac上兼容安装Python3并保留原先的Python2.7

前言 博主的电脑为2017款macbook pro ,电脑自带python2.7版本,在网上查资料得知由于很多系统服务依赖于自带的2.7py,所以不敢卸载,因此只能安装双兼容python,这里以Python3.7版本为例。 1、安装Xcode Command Line Too…

javafx中的tree_JavaFX中的塔防

javafx中的tree我想长时间使用我的游戏引擎来编写《塔防》游戏,但是由于另一个小组努力创建JavaFX《塔防》游戏,所以我认为我宁愿创建另一款游戏。 从邮件列表中,我了解到不再开发其他游戏。 因此,我决定尝试一下。 塔防是一款非…

ubuntu linux theme,如何在Ubuntu 20.04中启用全局暗黑主题

Ubuntu 20.04在设置实用程序中引入了新的Dark暗模式。但是,当您在Gnome Shell中将其打开时,它并不是完全暗黑。系统任务栏菜单,顶部栏中的日历,通知弹出窗口和桌面上下文菜单不是暗的,而且当您在 Light,Dar…