日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

分叉并加入Java 7 – JSR 166并发实用程序

發布時間:2023/12/3 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分叉并加入Java 7 – JSR 166并发实用程序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Java 7最有趣的改進之一是對并發的更好支持。 使用JSR 166并發實用程序,我們可以對并發進行一些非常有用的改進。 在我看來,fork-join庫在軟件工程中具有很高的實際應用潛力。 Fork and join為算法提供了非常簡單的編程模型,可以將其實現為遞歸任務。 有很多算法可以使用分治法來實現。

在未來幾年中,我們將看到標準臺式機,筆記本電腦和服務器計算機中內核的數量不斷增加。 原因很簡單:添加額外的內核比構建更快的單個處理器便宜。 因此,我們將不得不編寫更多支持并發的軟件以利用更好的硬件。

老實說,我不喜歡并發。 我的個人規則是“您需要一個充分的理由來實現并發,并且如果需要做的話必須非常小心。”在過去的幾年中,我看到的錯誤實現多于工作。 這就是為什么我喜歡fork&join庫的原因。 清晰的編程模型可實現樣板代碼,可防止您出錯。 但是,如果您打算使用fork和join,請花一些時間來了解其行為。

文件#1和#2中的示例與Java 7文檔中的示例代碼非常相似。 通常,使用遞歸算法的斐波那契數不是一個好主意,因為存在更好的線性解決方案(請比較http://nayuki.eigenstate.org/page/fast-fibonacci-algorithms ),但它更易于實現和理解相對于其它的。 因此,讓我們看一下示例:

// File #1: FibonacciTask.java [error handling, parameter validation and asserts removed] package com.sprunck.sample;import java.util.concurrent.RecursiveTask;public class FibonacciTask extends RecursiveTask<Long> {private static final long serialVersionUID = 1L;private final long inputValue;public FibonacciTask(long inputValue) {this.inputValue = inputValue;}@Overridepublic Long compute() {if (inputValue == 0L) {return 0L;} else if (inputValue <= 2L) {return 1L;} else {final FibonacciTask firstWorker = new FibonacciTask(inputValue - 1L);firstWorker.fork();final FibonacciTask secondWorker = new FibonacciTask(inputValue - 2L);return secondWorker.compute() + firstWorker.join();}} }// File #2: FibonacciTaskTest.java package com.sprunck.sample;import java.util.concurrent.ForkJoinPool; import junit.framework.Assert; import org.junit.Test;public class FibonacciTaskTest {// it makes no sense to create more threads than available cores (no speed improvement here)private static final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();// create thread poolprivate final ForkJoinPool pool = new ForkJoinPool(AVAILABLE_PROCESSORS);@Testpublic void testFibonacciArray() {// more test data: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.htmllong results[] = { 0L, 1L, 1L, 2L, 3L, 5L, 8L, 13L, 21L, 34L, 55L, 89L, 144L, 233L, 377L, 610L, 987L, 1597L,2584L, 4181L, 6765L };for (int inputValue = 0; inputValue < results.length; inputValue++) {final FibonacciTask task = new FibonacciTask(inputValue);System.out.print("Fibonacci(" + inputValue + ") = ");final long result = pool.invoke(task);System.out.println(result);Assert.assertEquals(results[inputValue], result);}} }

// FibonacciTaskTest.java的輸出

Fibonacci(0) = 0 Fibonacci(1) = 1 Fibonacci(2) = 1 Fibonacci(3) = 2 Fibonacci(4) = 3 Fibonacci(5) = 5 Fibonacci(6) = 8 Fibonacci(7) = 13 Fibonacci(8) = 21 Fibonacci(9) = 34 Fibonacci(10) = 55 Fibonacci(11) = 89 Fibonacci(12) = 144 Fibonacci(13) = 233 Fibonacci(14) = 377 Fibonacci(15) = 610 Fibonacci(16) = 987 Fibonacci(17) = 1597 Fibonacci(18) = 2584 Fibonacci(19) = 4181 Fibonacci(20) = 6765

到目前為止,這是一個簡單明了的解決方案。 沒有用于并行的樣板代碼,例如線程同步。

但我想鼓勵您更深入地了解解決方案中發生的情況。 在文件#3和#4中,您可以找到同一程序的增強版本。 第一個版本和第二個版本之間的唯一區別是,一些代碼可以跟蹤執行期間發生的事情,而較小的slowTask()可以模擬更實際的行為。

// File #3: FibonacciTaskTraces.java package com.sprunck.sample;import java.util.concurrent.RecursiveTask;public class FibonacciTaskTraces extends RecursiveTask<Long> {private static final long serialVersionUID = 1L;// just needed to format debug outputpublic static final String OUTPUT_PREFIX = " | ";private final String prefix;private final long inputValue;public FibonacciTaskTraces(long inputValue, final String prefix) {this.inputValue = inputValue;this.prefix = prefix;}@Overridepublic Long compute() {if (inputValue == 0L) {slowTask();return 0L;} else if (inputValue <= 2L) {slowTask();return 1L;} else {final long firstValue = inputValue - 1L;System.out.println(prefix + " - Fibonacci(" + firstValue + ") <- " + Thread.currentThread().getName()+ " (fork) ");final FibonacciTaskTraces firstWorker = new FibonacciTaskTraces(firstValue, prefix + OUTPUT_PREFIX);firstWorker.fork();final long secondValue = inputValue - 2L;System.out.println(prefix + " - Fibonacci(" + secondValue + ") <- " + Thread.currentThread().getName());final FibonacciTaskTraces secondWorker = new FibonacciTaskTraces(secondValue, prefix + OUTPUT_PREFIX);long result = secondWorker.compute() + firstWorker.join();System.out.println(prefix + " - Fibonacci(" + inputValue + ") = " + result + " <- "+ Thread.currentThread().getName() + " (join)");slowTask();return result;}}/** just simulate a longer running task (with out disturbing the other threads) */private void slowTask() {for (int k = 0, i = 0; i < 1000 * 1000 * 100; i++) {i = i + k;}} }// File #4: FibonacciTaskTracesTask.javapackage com.sprunck.sample;import java.util.concurrent.ForkJoinPool; import junit.framework.Assert; import org.junit.Test;public class FibonacciTaskTracesTest {// it makes no sense to create more threads than available cores (no speed improvement here)private static final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();// create thread poolprivate final ForkJoinPool pool = new ForkJoinPool(AVAILABLE_PROCESSORS);@Testpublic void testFibonacciArrayTraces() {// more test data: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.htmllong results[] = { 0L, 1L, 1L, 2L, 3L, 5L, 8L, 13L };for (int inputValue = 0; inputValue < results.length; inputValue++) {final FibonacciTaskTraces task = new FibonacciTaskTraces(inputValue, " | ");System.out.println("invoke Fibonacci(" + inputValue + ") <- " + Thread.currentThread().getName());final long result = pool.invoke(task);System.out.println("result = " + result + "\n");Assert.assertEquals(results[inputValue], result);}} }

// FibonacciTaskTracesTest.java的輸出

invoke Fibonacci(0) <- mainresult = 0invoke Fibonacci(1) <- mainresult = 1invoke Fibonacci(2) <- mainresult = 1invoke Fibonacci(3) <- main| - Fibonacci(2) <- ForkJoinPool-1-worker-1 (fork) | - Fibonacci(1) <- ForkJoinPool-1-worker-1| - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-1 (join)result = 2invoke Fibonacci(4) <- main| - Fibonacci(3) <- ForkJoinPool-1-worker-1 (fork) | - Fibonacci(2) <- ForkJoinPool-1-worker-1| | - Fibonacci(2) <- ForkJoinPool-1-worker-2 (fork) | | - Fibonacci(1) <- ForkJoinPool-1-worker-2| | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-2 (join)| - Fibonacci(4) = 3 <- ForkJoinPool-1-worker-1 (join)result = 3invoke Fibonacci(5) <- main| - Fibonacci(4) <- ForkJoinPool-1-worker-1 (fork) | - Fibonacci(3) <- ForkJoinPool-1-worker-1| | - Fibonacci(2) <- ForkJoinPool-1-worker-1 (fork) | | - Fibonacci(1) <- ForkJoinPool-1-worker-1| | - Fibonacci(3) <- ForkJoinPool-1-worker-2 (fork) | | - Fibonacci(2) <- ForkJoinPool-1-worker-2| | | - Fibonacci(2) <- ForkJoinPool-1-worker-2 (fork) | | | - Fibonacci(1) <- ForkJoinPool-1-worker-2| | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-1 (join)| | | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-2 (join)| | - Fibonacci(4) = 3 <- ForkJoinPool-1-worker-2 (join)| - Fibonacci(5) = 5 <- ForkJoinPool-1-worker-1 (join)result = 5invoke Fibonacci(6) <- main| - Fibonacci(5) <- ForkJoinPool-1-worker-1 (fork) | - Fibonacci(4) <- ForkJoinPool-1-worker-1| | - Fibonacci(3) <- ForkJoinPool-1-worker-1 (fork) | | - Fibonacci(2) <- ForkJoinPool-1-worker-1| | - Fibonacci(4) <- ForkJoinPool-1-worker-2 (fork) | | - Fibonacci(3) <- ForkJoinPool-1-worker-2| | | - Fibonacci(2) <- ForkJoinPool-1-worker-2 (fork) | | | - Fibonacci(1) <- ForkJoinPool-1-worker-2| | | - Fibonacci(2) <- ForkJoinPool-1-worker-1 (fork) | | | - Fibonacci(1) <- ForkJoinPool-1-worker-1| | | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-2 (join)| | | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-1 (join)| | | - Fibonacci(3) <- ForkJoinPool-1-worker-2 (fork) | | | - Fibonacci(2) <- ForkJoinPool-1-worker-2| | - Fibonacci(4) = 3 <- ForkJoinPool-1-worker-1 (join)| | | | - Fibonacci(2) <- ForkJoinPool-1-worker-2 (fork) | | | | - Fibonacci(1) <- ForkJoinPool-1-worker-2| | | | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-2 (join)| | | - Fibonacci(4) = 3 <- ForkJoinPool-1-worker-2 (join)| | - Fibonacci(5) = 5 <- ForkJoinPool-1-worker-2 (join)| - Fibonacci(6) = 8 <- ForkJoinPool-1-worker-1 (join)result = 8invoke Fibonacci(7) <- main| - Fibonacci(6) <- ForkJoinPool-1-worker-1 (fork) | - Fibonacci(5) <- ForkJoinPool-1-worker-1| | - Fibonacci(4) <- ForkJoinPool-1-worker-1 (fork) | | - Fibonacci(3) <- ForkJoinPool-1-worker-1| | | - Fibonacci(2) <- ForkJoinPool-1-worker-1 (fork) | | | - Fibonacci(1) <- ForkJoinPool-1-worker-1| | - Fibonacci(5) <- ForkJoinPool-1-worker-2 (fork) | | - Fibonacci(4) <- ForkJoinPool-1-worker-2| | | - Fibonacci(3) <- ForkJoinPool-1-worker-2 (fork) | | | - Fibonacci(2) <- ForkJoinPool-1-worker-2| | | | - Fibonacci(2) <- ForkJoinPool-1-worker-2 (fork) | | | | - Fibonacci(1) <- ForkJoinPool-1-worker-2| | | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-1 (join)| | | - Fibonacci(3) <- ForkJoinPool-1-worker-1 (fork) | | | - Fibonacci(2) <- ForkJoinPool-1-worker-1| | | | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-2 (join)| | | | - Fibonacci(2) <- ForkJoinPool-1-worker-1 (fork) | | | | - Fibonacci(1) <- ForkJoinPool-1-worker-1| | | - Fibonacci(4) = 3 <- ForkJoinPool-1-worker-2 (join)| | | - Fibonacci(4) <- ForkJoinPool-1-worker-2 (fork) | | | - Fibonacci(3) <- ForkJoinPool-1-worker-2| | | | - Fibonacci(2) <- ForkJoinPool-1-worker-2 (fork) | | | | - Fibonacci(1) <- ForkJoinPool-1-worker-2| | | | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-1 (join)| | | - Fibonacci(4) = 3 <- ForkJoinPool-1-worker-1 (join)| | | | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-2 (join)| | - Fibonacci(5) = 5 <- ForkJoinPool-1-worker-1 (join)| | | | - Fibonacci(3) <- ForkJoinPool-1-worker-2 (fork) | | | | - Fibonacci(2) <- ForkJoinPool-1-worker-2| | | | | - Fibonacci(2) <- ForkJoinPool-1-worker-1 (fork) | | | | | - Fibonacci(1) <- ForkJoinPool-1-worker-1| | | | | - Fibonacci(3) = 2 <- ForkJoinPool-1-worker-1 (join)| | | | - Fibonacci(4) = 3 <- ForkJoinPool-1-worker-2 (join)| | | - Fibonacci(5) = 5 <- ForkJoinPool-1-worker-2 (join)| | - Fibonacci(6) = 8 <- ForkJoinPool-1-worker-2 (join)| - Fibonacci(7) = 13 <- ForkJoinPool-1-worker-1 (join)result = 13

現在,輸出使您可以更深入地了解程序的處理。 出現以下斐波納契數計算方法:

  • 前三個斐波那契數在主線程中處理,
  • 下一個斐波那契數僅在一個新線程(ForkJoinPool-1-worker-1)中處理,并且
  • 從第五個斐波納契數開始,使用了兩個線程(ForkJoinPool-1-worker-1和ForkJoinPool-1-worker-2)。

該算法效率低下,因為在處理過程中有很多冗余操作(重新計算相同的斐波那契數)。 在現實生活中的應用程序中,您應該小心使用這種效率低下的算法。 一些痕跡有助于理解會發生什么。

推薦品

  • 使用fork和join既簡單又直接,但是要花一些時間來跟蹤和理解您的實現。
  • 有時實現同一算法的兩個版本(一個用于分析,另一個用于生產)會有所幫助。
  • 花一些時間來設計和理解更好的并發算法是一項不錯的投資。
  • 以此方式開發了概率計算器 ( 概率計算器演示– PCALC )。

    參考: 如何在Java 7 – JSR 166并發實用程序中實現fork and join? 由我們的JCG合作伙伴 Markus Sprunck在Software Engineering Candies博客上獲得。


    翻譯自: https://www.javacodegeeks.com/2012/04/fork-and-join-in-java-7-jsr-166.html

    總結

    以上是生活随笔為你收集整理的分叉并加入Java 7 – JSR 166并发实用程序的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。