Java 8 Streams API作为友好的ForkJoinPool外观
我最喜歡Java 8的功能之一是流API。 最終,它消除了代碼中的幾乎所有循環,并使您可以編寫更具表現力和重點的代碼。
今天,我意識到它可以用于其他用途:作為ForkJoinPool一個不錯的前端。
問題:執行器樣板
假設我們要并行運行許多任務。 沒什么好說的,讓我們說它們每個都只是打印出執行線程的名稱(因此我們可以看到它并行運行)。 我們要在完成所有操作后恢復執行。
如果要使用ExecutorService并行運行一堆任務,則可能需要執行以下操作:
ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 0; i < 5; i++) {executor.submit(() -> System.out.println(Thread.currentThread())); } executor.shutdown(); try {executor.awaitTermination(1, TimeUnit.SECONDS); } catch (InterruptedException ex) {// TODO handle... }現在,這是很多代碼! 但是我們可以做得更好。
解決方案:流API
最后,我想到了這個實用程序:
void doInParallelNTimes(int times, Runnable op) {IntStream.range(0, times).parallel().forEach(i -> op.run()); }可重復使用的一切。 像這樣稱呼它:
doInParallelNTimes(5, () -> System.out.println(Thread.currentThread()));做完了
這打印出以下內容。 請注意,它實際上也在使用主線程-因為它仍然被扣為人質,并且在執行完成之前無法恢復。
Thread[main,5,main] Thread[ForkJoinPool.commonPool-worker-1,5,main] Thread[main,5,main] Thread[ForkJoinPool.commonPool-worker-3,5,main] Thread[ForkJoinPool.commonPool-worker-2,5,main]另一個例子:并行計算
這是另一個例子。 我們可以使用流API并行處理許多不同的任務,而不必重復執行N次相同的操作。 我們可以創建(“種子”)具有任何集合或值集的流,對其并行執行一個函數,最后匯總結果(集合為一個集合,減少為單個值等)。
讓我們看看如何計算前45個斐波納契數的總和:
public class Tester {public static void main(String[] args) {Stopwatch stopwatch = Stopwatch.createStarted();IntStream.range(1, 45).parallel().map(Tester::fib).sum();System.out.println("Parallel took " + stopwatch.elapsed(MILLISECONDS) + " ms");stopwatch.reset();stopwatch.start();IntStream.range(1, 45).map(Tester::fib).sum();System.out.println("Sequential took " + stopwatch.elapsed(MILLISECONDS) + " ms");}private static int fib(int n) {if (n == 1 || n == 2) {return 1;} else {return fib(n - 1) + fib(n - 2);}} }打印輸出:
Parallel took 3078 ms Sequential took 7327 ms它在一行代碼中取得了很多成就。 首先,它創建一個流,其中包含我們要并行運行的所有任務的描述。 然后,它并行調用所有這些函數。 最后,它返回所有這些結果的總和。
并非所有人為。 我可以輕松想象創建具有任意值(包括豐富的Java對象)的流,并對它們執行非平凡的操作。 沒關系,編排所有看起來仍然相同的東西。
什么時候做?
我認為這種解決方案在所有情況下都非常有用,當您事先知道負載,并且您希望將執行分叉到多個線程并在它們全部完成后恢復。 我需要一些測試代碼,但它可能在許多其他派生/合并或分而治之方案中很好地工作。
顯然,如果您想在后臺運行某些程序并恢復執行,或者想讓后臺執行程序長時間運行,則無法使用。
翻譯自: https://www.javacodegeeks.com/2015/01/java-8-streams-api-as-friendly-forkjoinpool-facade.html
總結
以上是生活随笔為你收集整理的Java 8 Streams API作为友好的ForkJoinPool外观的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 问界新M7开启预售:25.8-31.8万
- 下一篇: 在三个Java IDE中生成的三种常见方