网站建设及推广话术,wordpress 主题 psd,做网站赚钱 2017,wordpress更改主题并行代码是在多个线程上运行的代码#xff0c;曾经是许多经验丰富的开发人员的噩梦#xff0c;但是Java 8带来了许多更改#xff0c;这些更改应该使这种提高性能的技巧更加易于管理。 并行流 在Java 8之前#xff0c;并行#xff08;或并发#xff09;代码与顺序代码之间… 并行代码是在多个线程上运行的代码曾经是许多经验丰富的开发人员的噩梦但是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同时实现Future和CompletionStage接口。 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直到上一步完成为止。 异步处理 上述所有回调方法也都具有异步版本 thenRunAsync thenApplyAsync等。这些版本可以在自己的线程上运行它们为您提供了额外的控制权因为您可以告诉它要使用哪个ForkJoinPool 。 如果您不使用异步版本则所有回调将在同一线程上执行。 当事情出错时 当出现问题时将使用exceptionally方法来处理异常。 您可以给它提供一个方法该方法返回一个值以返回数据轨道或引发新异常。 …
.exceptionally(ex → new Foo())
.thenAccept(this::bar);合并和撰写 您可以使用thenCompose方法链接多个CompletableFutures 。 没有它结果将嵌套CompletableFutures 。 这使得thenCompose和thenApply像flatMap和map用于流。 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