From a0ca3927b24cb9ebab8fbd3ca3d754e1c6fb5b15 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Wed, 6 Nov 2024 09:13:47 +0900 Subject: [PATCH 01/16] Add approaches for Parallel-Letter-Frequency --- .../.approaches/config.json | 27 ++++ .../.approaches/fork-join/content.md | 90 ++++++++++++ .../.approaches/fork-join/snippet.txt | 7 + .../.approaches/introduction.md | 138 ++++++++++++++++++ .../.approaches/parallel-stream/content.md | 49 +++++++ .../.approaches/parallel-stream/snippet.txt | 7 + 6 files changed, 318 insertions(+) create mode 100644 exercises/practice/parallel-letter-frequency/.approaches/config.json create mode 100644 exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md create mode 100644 exercises/practice/parallel-letter-frequency/.approaches/fork-join/snippet.txt create mode 100644 exercises/practice/parallel-letter-frequency/.approaches/introduction.md create mode 100644 exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md create mode 100644 exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/snippet.txt diff --git a/exercises/practice/parallel-letter-frequency/.approaches/config.json b/exercises/practice/parallel-letter-frequency/.approaches/config.json new file mode 100644 index 000000000..dad02090c --- /dev/null +++ b/exercises/practice/parallel-letter-frequency/.approaches/config.json @@ -0,0 +1,27 @@ +{ + "introduction": { + "authors": [ + "masiljangajji" + ] + }, + "approaches": [ + { + "uuid": "dee2a79d-3e64-4220-b99f-55667549c12c", + "slug": "fork-join", + "title": "Fork/Join", + "blurb": "Parallel Computation Using Fork/Join", + "authors": [ + "masiljangajji" + ] + }, + { + "uuid": "75e9e93b-4da4-4474-8b6e-3c0cb9b3a9bb", + "slug": "parallel-stream", + "title": "Parallel Stream", + "blurb": "Parallel Computation Using Parallel Stream", + "authors": [ + "masiljangajji" + ] + } + ] +} diff --git a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md new file mode 100644 index 000000000..a92d88e9d --- /dev/null +++ b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md @@ -0,0 +1,90 @@ +# `Fork/Join` + +```java +import java.util.Map; +import java.util.List; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.RecursiveTask; + +class ParallelLetterFrequency { + + List texts; + ConcurrentMap letterCount; + + ParallelLetterFrequency(String[] texts) { + this.texts = List.of(texts); + letterCount = new ConcurrentHashMap<>(); + } + + Map countLetters() { + if (texts.isEmpty()) { + return letterCount; + } + + ForkJoinPool forkJoinPool = new ForkJoinPool(); + forkJoinPool.invoke(new LetterCountTask(texts, 0, texts.size(), letterCount)); + forkJoinPool.shutdown(); + + return letterCount; + } + + private static class LetterCountTask extends RecursiveTask { + private static final int THRESHOLD = 10; + private final List texts; + private final int start; + private final int end; + private final ConcurrentMap letterCount; + + LetterCountTask(List texts, int start, int end, ConcurrentMap letterCount) { + this.texts = texts; + this.start = start; + this.end = end; + this.letterCount = letterCount; + } + + @Override + protected Void compute() { + if (end - start <= THRESHOLD) { + for (int i = start; i < end; i++) { + for (char c : texts.get(i).toLowerCase().toCharArray()) { + if (Character.isAlphabetic(c)) { + letterCount.merge(c, 1, Integer::sum); + } + } + } + } else { + int mid = (start + end) / 2; + LetterCountTask leftTask = new LetterCountTask(texts, start, mid, letterCount); + LetterCountTask rightTask = new LetterCountTask(texts, mid, end, letterCount); + invokeAll(leftTask, rightTask); + } + return null; + } + } +} +``` + +Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting and updates are safely handled in a parallel environment. + +If there are no strings, a validation step prevents unnecessary processing. + +A [`ForkJoinPool`][ForkJoinPool] is then created. The core of [`ForkJoinPool`][ForkJoinPool] is the Fork/Join mechanism, which divides tasks into smaller units and processes them in parallel. + +THRESHOLD is the criterion for task division. If the range of texts exceeds the THRESHOLD, the task is divided into two subtasks, and [`invokeAll`][invokeAll](leftTask, rightTask) is called to execute both tasks in parallel. + +Each subtask in LetterCountTask will continue calling compute() to divide itself further until the range is smaller than or equal to the threshold. + +For tasks that are within the threshold, letter frequency is calculated. The [`isAlphabetic`][isAlphabetic] method is used to identify all characters classified as alphabetic in Unicode, covering various languages like English, Korean, Japanese, Chinese, etc., returning true for alphabetic characters and false for numbers, special characters, spaces, and others. + +Additionally, since uppercase and lowercase letters are treated as the same character (e.g., A and a), each character is converted to lowercase. + +After updating letter frequencies, the final map is returned. + + + +[ConcurrentHashMap]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html +[ForkJoinPool]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html +[isAlphabetic]: https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isAlphabetic-int- +[invokeAll]: https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html diff --git a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/snippet.txt b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/snippet.txt new file mode 100644 index 000000000..7e782eb30 --- /dev/null +++ b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/snippet.txt @@ -0,0 +1,7 @@ +for (int i = start; i < end; i++) { + for (char c : texts.get(i).toLowerCase().toCharArray()) { + if (Character.isAlphabetic(c)) { + letterCount.merge(c, 1, Integer::sum); + } + } +} \ No newline at end of file diff --git a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md new file mode 100644 index 000000000..7cbbc11b1 --- /dev/null +++ b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md @@ -0,0 +1,138 @@ +# Introduction + +There are multiple ways to solve the Parallel Letter Frequency problem. +One approach is to use parallelStream, and another involves using ForkJoinPool. + +## General guidance + +To count occurrences of items, a map data structure is often used, though arrays and lists can work as well. A map, being a key-value pair structure, is suitable for recording frequency by incrementing the value for each key. + +If the data being counted has a limited range (e.g., characters or integers), an int[] array or List can be used to record frequencies. + +Parallel processing typically takes place in a multi-[`thread`][thread] environment. The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the parallelStream() method. With parallelStream(), developers can use the ForkJoinPool model for workload division and parallel execution, without the need to manually manage threads or create custom thread pools. + +The [`ForkJoinPool`][ForkJoinPool] class, optimized for dividing and managing tasks, makes parallel processing efficient. + +However, parallelStream() uses the common ForkJoinPool by default, meaning multiple parallelStream instances share the same thread pool unless configured otherwise. As a result, parallel streams may interfere with each other when sharing this thread pool, potentially affecting performance. + +Although this doesn’t directly impact solving the Parallel Letter Frequency problem, it may introduce issues when thread pool sharing causes conflicts in other applications. Therefore, a custom ForkJoinPool approach is also provided below. + + +## Approach: `parallelStream` + +```java +import java.util.Map; +import java.util.List; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; + +class ParallelLetterFrequency { + + List texts; + ConcurrentMap letterCount; + + ParallelLetterFrequency(String[] texts) { + this.texts = List.of(texts); + letterCount = new ConcurrentHashMap<>(); + } + + Map countLetters() { + if (!letterCount.isEmpty() || texts.isEmpty()) { + return letterCount; + } + texts.parallelStream().forEach(text -> { + for (char c: text.toLowerCase().toCharArray()) { + if (Character.isAlphabetic(c)) { + letterCount.merge(c, 1, Integer::sum); + } + } + }); + return letterCount; + } + +} +``` + +For more information, check the [`parallelStream` approach][approach-parallel-stream]. + +## Approach: `Fork/Join` + +```java +import java.util.Map; +import java.util.List; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.RecursiveTask; + +class ParallelLetterFrequency { + + List texts; + ConcurrentMap letterCount; + + ParallelLetterFrequency(String[] texts) { + this.texts = List.of(texts); + letterCount = new ConcurrentHashMap<>(); + } + + Map countLetters() { + if (!letterCount.isEmpty() || texts.isEmpty()) { + return letterCount; + } + + ForkJoinPool forkJoinPool = new ForkJoinPool(); + forkJoinPool.invoke(new LetterCountTask(texts, 0, texts.size(), letterCount)); + forkJoinPool.shutdown(); + + return letterCount; + } + + private static class LetterCountTask extends RecursiveTask { + private static final int THRESHOLD = 10; + private final List texts; + private final int start; + private final int end; + private final ConcurrentMap letterCount; + + LetterCountTask(List texts, int start, int end, ConcurrentMap letterCount) { + this.texts = texts; + this.start = start; + this.end = end; + this.letterCount = letterCount; + } + + @Override + protected Void compute() { + if (end - start <= THRESHOLD) { + for (int i = start; i < end; i++) { + for (char c : texts.get(i).toLowerCase().toCharArray()) { + if (Character.isAlphabetic(c)) { + letterCount.merge(c, 1, Integer::sum); + } + } + } + } else { + int mid = (start + end) / 2; + LetterCountTask leftTask = new LetterCountTask(texts, start, mid, letterCount); + LetterCountTask rightTask = new LetterCountTask(texts, mid, end, letterCount); + invokeAll(leftTask, rightTask); + } + return null; + } + } +} + +``` + +For more information, check the [`fork/join` approach][approach-fork-join]. + +## Which approach to use? + +When tasks are simple or do not require a dedicated thread pool (such as in this case), the parallelStream approach is recommended. +However, if the work is complex or there is a need to isolate thread pools from other concurrent tasks, the ForkJoinPool approach is preferable. + +[thread]: https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html +[stream]: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html +[ForkJoinPool]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html +[approach-parallel-stream]: https://exercism.org/tracks/java/exercises/parallel-letter-frequency/approaches/parallel-stream +[approach-fork-join]: https://exercism.org/tracks/java/exercises/parallel-letter-frequency/approaches/fork-join diff --git a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md new file mode 100644 index 000000000..bf1f93c27 --- /dev/null +++ b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md @@ -0,0 +1,49 @@ +# `parallelStream` + +```java +import java.util.Map; +import java.util.List; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; + +class ParallelLetterFrequency { + + List texts; + ConcurrentMap letterCount; + + ParallelLetterFrequency(String[] texts) { + this.texts = List.of(texts); + letterCount = new ConcurrentHashMap<>(); + } + + Map countLetters() { + if (texts.isEmpty()) { + return letterCount; + } + texts.parallelStream().forEach(text -> { + for (char c: text.toLowerCase().toCharArray()) { + if (Character.isAlphabetic(c)) { + letterCount.merge(c, 1, Integer::sum); + } + } + }); + return letterCount; + } + +} +``` + +Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting and updates are safely handled in a parallel environment. + +If there are no strings to process, a validation step avoids unnecessary computation. + +To calculate letter frequency, a parallel stream is used. The [`isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning true. Non-alphabetic characters, including numbers, special characters, and spaces, return false. + +Since we treat uppercase and lowercase letters as the same character (e.g., A and a), characters are converted to lowercase. + +After updating letter frequencies, the final map is returned. + + + +[ConcurrentHashMap]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html +[isAlphabetic]: https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isAlphabetic-int- diff --git a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/snippet.txt b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/snippet.txt new file mode 100644 index 000000000..9cbb9cffa --- /dev/null +++ b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/snippet.txt @@ -0,0 +1,7 @@ +texts.parallelStream().forEach(text -> { + for (char c: text.toLowerCase().toCharArray()) { + if (Character.isAlphabetic(c)) { + letterCount.merge(c, 1, Integer::sum); + } + } +}); \ No newline at end of file From b84ea23641f9f1e3a451132ce971e89277063fe5 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Tue, 12 Nov 2024 22:59:17 +0900 Subject: [PATCH 02/16] fix: markdown according to the rules --- .github/PULL_REQUEST_TEMPLATE.md | 2 -- .../.approaches/fork-join/content.md | 6 ++---- .../parallel-letter-frequency/.approaches/introduction.md | 3 +-- .../.approaches/parallel-stream/content.md | 4 +--- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d07adf074..35abb3274 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,8 +2,6 @@ - - --- diff --git a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md index a92d88e9d..fbc7b89f3 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md @@ -1,4 +1,4 @@ -# `Fork/Join` +# `Fork/Join` ```java import java.util.Map; @@ -11,7 +11,7 @@ import java.util.concurrent.RecursiveTask; class ParallelLetterFrequency { List texts; - ConcurrentMap letterCount; + ConcurrentMap letterCount; ParallelLetterFrequency(String[] texts) { this.texts = List.of(texts); @@ -82,8 +82,6 @@ Additionally, since uppercase and lowercase letters are treated as the same char After updating letter frequencies, the final map is returned. - - [ConcurrentHashMap]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html [ForkJoinPool]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html [isAlphabetic]: https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isAlphabetic-int- diff --git a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md index 7cbbc11b1..94d23a243 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md @@ -17,8 +17,7 @@ However, parallelStream() uses the common ForkJoinPool by default, meaning multi Although this doesn’t directly impact solving the Parallel Letter Frequency problem, it may introduce issues when thread pool sharing causes conflicts in other applications. Therefore, a custom ForkJoinPool approach is also provided below. - -## Approach: `parallelStream` +## Approach: `parallelStream` ```java import java.util.Map; diff --git a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md index bf1f93c27..0e2860861 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md @@ -1,4 +1,4 @@ -# `parallelStream` +# `parallelStream` ```java import java.util.Map; @@ -43,7 +43,5 @@ Since we treat uppercase and lowercase letters as the same character (e.g., A an After updating letter frequencies, the final map is returned. - - [ConcurrentHashMap]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html [isAlphabetic]: https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isAlphabetic-int- From 4007c38f00a203a1529b2c11a45d99e9afe7fb68 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 01:06:12 +0900 Subject: [PATCH 03/16] docs: undo PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 35abb3274..d07adf074 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,6 +2,8 @@ + + --- From 616bcc2c1418817ee221dba26480edbf82ee05dd Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 01:07:00 +0900 Subject: [PATCH 04/16] docs: make it clear the method is from the Character --- .../parallel-letter-frequency/.approaches/fork-join/content.md | 2 +- .../.approaches/parallel-stream/content.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md index fbc7b89f3..00bf8a086 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md @@ -76,7 +76,7 @@ THRESHOLD is the criterion for task division. If the range of texts exceeds the Each subtask in LetterCountTask will continue calling compute() to divide itself further until the range is smaller than or equal to the threshold. -For tasks that are within the threshold, letter frequency is calculated. The [`isAlphabetic`][isAlphabetic] method is used to identify all characters classified as alphabetic in Unicode, covering various languages like English, Korean, Japanese, Chinese, etc., returning true for alphabetic characters and false for numbers, special characters, spaces, and others. +For tasks that are within the threshold, letter frequency is calculated. The [`Character.isAlphabetic`][isAlphabetic] method is used to identify all characters classified as alphabetic in Unicode, covering various languages like English, Korean, Japanese, Chinese, etc., returning true for alphabetic characters and false for numbers, special characters, spaces, and others. Additionally, since uppercase and lowercase letters are treated as the same character (e.g., A and a), each character is converted to lowercase. diff --git a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md index 0e2860861..167b8b94a 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md @@ -37,7 +37,7 @@ Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting a If there are no strings to process, a validation step avoids unnecessary computation. -To calculate letter frequency, a parallel stream is used. The [`isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning true. Non-alphabetic characters, including numbers, special characters, and spaces, return false. +To calculate letter frequency, a parallel stream is used. The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning true. Non-alphabetic characters, including numbers, special characters, and spaces, return false. Since we treat uppercase and lowercase letters as the same character (e.g., A and a), characters are converted to lowercase. From 1f0531d1d171e1add0704b9f478f9b329ad4e2b6 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 01:08:42 +0900 Subject: [PATCH 05/16] docs: update(introduction.md) markdown format --- .../parallel-letter-frequency/.approaches/introduction.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md index 94d23a243..5b25417f3 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md @@ -5,7 +5,9 @@ One approach is to use parallelStream, and another involves using ForkJoinPool. ## General guidance -To count occurrences of items, a map data structure is often used, though arrays and lists can work as well. A map, being a key-value pair structure, is suitable for recording frequency by incrementing the value for each key. +To count occurrences of items, a map data structure is often used, though arrays and lists can work as well. + +A map, being a key-value pair structure, is suitable for recording frequency by incrementing the value for each key. If the data being counted has a limited range (e.g., characters or integers), an int[] array or List can be used to record frequencies. From 28a8ebcde865444280663a6108b5f35d584cd4dc Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 01:28:35 +0900 Subject: [PATCH 06/16] docs: update markdown format and make it clear the method --- .../.approaches/fork-join/content.md | 12 +++++++--- .../.approaches/introduction.md | 23 ++++++++++++++----- .../.approaches/parallel-stream/content.md | 4 +++- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md index 00bf8a086..3c3897701 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md @@ -70,13 +70,19 @@ Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting a If there are no strings, a validation step prevents unnecessary processing. -A [`ForkJoinPool`][ForkJoinPool] is then created. The core of [`ForkJoinPool`][ForkJoinPool] is the Fork/Join mechanism, which divides tasks into smaller units and processes them in parallel. +A [`ForkJoinPool`][ForkJoinPool] is then created. -THRESHOLD is the criterion for task division. If the range of texts exceeds the THRESHOLD, the task is divided into two subtasks, and [`invokeAll`][invokeAll](leftTask, rightTask) is called to execute both tasks in parallel. +The core of [`ForkJoinPool`][ForkJoinPool] is the Fork/Join mechanism, which divides tasks into smaller units and processes them in parallel. + +THRESHOLD is the criterion for task division. + +If the range of texts exceeds the THRESHOLD, the task is divided into two subtasks, and [`invokeAll`][invokeAll](leftTask, rightTask) is called to execute both tasks in parallel. Each subtask in LetterCountTask will continue calling compute() to divide itself further until the range is smaller than or equal to the threshold. -For tasks that are within the threshold, letter frequency is calculated. The [`Character.isAlphabetic`][isAlphabetic] method is used to identify all characters classified as alphabetic in Unicode, covering various languages like English, Korean, Japanese, Chinese, etc., returning true for alphabetic characters and false for numbers, special characters, spaces, and others. +For tasks that are within the threshold, letter frequency is calculated. + +The [`Character.isAlphabetic`][isAlphabetic] method is used to identify all characters classified as alphabetic in Unicode, covering various languages like English, Korean, Japanese, Chinese, etc., returning true for alphabetic characters and false for numbers, special characters, spaces, and others. Additionally, since uppercase and lowercase letters are treated as the same character (e.g., A and a), each character is converted to lowercase. diff --git a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md index 5b25417f3..93f9e6f16 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md @@ -1,23 +1,32 @@ # Introduction There are multiple ways to solve the Parallel Letter Frequency problem. -One approach is to use parallelStream, and another involves using ForkJoinPool. + +One approach is to use [`Stream.parallelStream`][stream], and another involves using [`ForkJoinPool`][ForkJoinPool]. ## General guidance To count occurrences of items, a map data structure is often used, though arrays and lists can work as well. -A map, being a key-value pair structure, is suitable for recording frequency by incrementing the value for each key. +A [`map`][map], being a key-value pair structure, is suitable for recording frequency by incrementing the value for each key. + +If the data being counted has a limited range (e.g., characters or integers), an `int[] array` or [`List`][list] can be used to record frequencies. + +Parallel processing typically takes place in a multi-[`thread`][thread] environment. -If the data being counted has a limited range (e.g., characters or integers), an int[] array or List can be used to record frequencies. +The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the parallelStream() method. -Parallel processing typically takes place in a multi-[`thread`][thread] environment. The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the parallelStream() method. With parallelStream(), developers can use the ForkJoinPool model for workload division and parallel execution, without the need to manually manage threads or create custom thread pools. +With parallelStream(), developers can use the ForkJoinPool model for workload division and parallel execution, without the need to manually manage threads or create custom thread pools. The [`ForkJoinPool`][ForkJoinPool] class, optimized for dividing and managing tasks, makes parallel processing efficient. -However, parallelStream() uses the common ForkJoinPool by default, meaning multiple parallelStream instances share the same thread pool unless configured otherwise. As a result, parallel streams may interfere with each other when sharing this thread pool, potentially affecting performance. +However, parallelStream() uses the common ForkJoinPool by default, meaning multiple parallelStream instances share the same thread pool unless configured otherwise. + +As a result, parallel streams may interfere with each other when sharing this thread pool, potentially affecting performance. + +Although this doesn’t directly impact solving the Parallel Letter Frequency problem, it may introduce issues when thread pool sharing causes conflicts in other applications. -Although this doesn’t directly impact solving the Parallel Letter Frequency problem, it may introduce issues when thread pool sharing causes conflicts in other applications. Therefore, a custom ForkJoinPool approach is also provided below. +Therefore, a custom ForkJoinPool approach is also provided below. ## Approach: `parallelStream` @@ -135,5 +144,7 @@ However, if the work is complex or there is a need to isolate thread pools from [thread]: https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html [stream]: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html [ForkJoinPool]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html +[map]: https://docs.oracle.com/javase/8/docs/api/?java/util/Map.html +[list]: https://docs.oracle.com/javase/8/docs/api/?java/util/List.html [approach-parallel-stream]: https://exercism.org/tracks/java/exercises/parallel-letter-frequency/approaches/parallel-stream [approach-fork-join]: https://exercism.org/tracks/java/exercises/parallel-letter-frequency/approaches/fork-join diff --git a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md index 167b8b94a..1373fb5de 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md @@ -37,7 +37,9 @@ Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting a If there are no strings to process, a validation step avoids unnecessary computation. -To calculate letter frequency, a parallel stream is used. The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning true. Non-alphabetic characters, including numbers, special characters, and spaces, return false. +To calculate letter frequency, a parallel stream is used. + +The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning true. Non-alphabetic characters, including numbers, special characters, and spaces, return false. Since we treat uppercase and lowercase letters as the same character (e.g., A and a), characters are converted to lowercase. From 49512f7585fe140c16689b21c38e21473e8f4c23 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 01:39:36 +0900 Subject: [PATCH 07/16] docs: update markdown format(markdownlint-cli2) --- .github/PULL_REQUEST_TEMPLATE.md | 2 -- .../.approaches/fork-join/content.md | 6 +++--- .../parallel-letter-frequency/.approaches/introduction.md | 8 ++++---- .../.approaches/parallel-stream/content.md | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d07adf074..35abb3274 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,8 +2,6 @@ - - --- diff --git a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md index 3c3897701..48865caf6 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md @@ -70,17 +70,17 @@ Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting a If there are no strings, a validation step prevents unnecessary processing. -A [`ForkJoinPool`][ForkJoinPool] is then created. +A [`ForkJoinPool`][ForkJoinPool] is then created. The core of [`ForkJoinPool`][ForkJoinPool] is the Fork/Join mechanism, which divides tasks into smaller units and processes them in parallel. -THRESHOLD is the criterion for task division. +THRESHOLD is the criterion for task division. If the range of texts exceeds the THRESHOLD, the task is divided into two subtasks, and [`invokeAll`][invokeAll](leftTask, rightTask) is called to execute both tasks in parallel. Each subtask in LetterCountTask will continue calling compute() to divide itself further until the range is smaller than or equal to the threshold. -For tasks that are within the threshold, letter frequency is calculated. +For tasks that are within the threshold, letter frequency is calculated. The [`Character.isAlphabetic`][isAlphabetic] method is used to identify all characters classified as alphabetic in Unicode, covering various languages like English, Korean, Japanese, Chinese, etc., returning true for alphabetic characters and false for numbers, special characters, spaces, and others. diff --git a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md index 93f9e6f16..828651cc5 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md @@ -12,19 +12,19 @@ A [`map`][map], being a key-value pair structure, is suitable for recording freq If the data being counted has a limited range (e.g., characters or integers), an `int[] array` or [`List`][list] can be used to record frequencies. -Parallel processing typically takes place in a multi-[`thread`][thread] environment. +Parallel processing typically takes place in a multi-[`thread`][thread] environment. -The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the parallelStream() method. +The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the parallelStream() method. With parallelStream(), developers can use the ForkJoinPool model for workload division and parallel execution, without the need to manually manage threads or create custom thread pools. The [`ForkJoinPool`][ForkJoinPool] class, optimized for dividing and managing tasks, makes parallel processing efficient. -However, parallelStream() uses the common ForkJoinPool by default, meaning multiple parallelStream instances share the same thread pool unless configured otherwise. +However, parallelStream() uses the common ForkJoinPool by default, meaning multiple parallelStream instances share the same thread pool unless configured otherwise. As a result, parallel streams may interfere with each other when sharing this thread pool, potentially affecting performance. -Although this doesn’t directly impact solving the Parallel Letter Frequency problem, it may introduce issues when thread pool sharing causes conflicts in other applications. +Although this doesn’t directly impact solving the Parallel Letter Frequency problem, it may introduce issues when thread pool sharing causes conflicts in other applications. Therefore, a custom ForkJoinPool approach is also provided below. diff --git a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md index 1373fb5de..b64e0a505 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md @@ -37,7 +37,7 @@ Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting a If there are no strings to process, a validation step avoids unnecessary computation. -To calculate letter frequency, a parallel stream is used. +To calculate letter frequency, a parallel stream is used. The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning true. Non-alphabetic characters, including numbers, special characters, and spaces, return false. From 42bee4548e42be9c5f9d6aea78ef520cd43f6669 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 20:19:04 +0900 Subject: [PATCH 08/16] docs: update markdown format(PULL_REQUEST_TEMPLATE.md) --- .github/PULL_REQUEST_TEMPLATE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 35abb3274..d07adf074 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,6 +2,8 @@ + + --- From faf10e02df158482b983e6fcef1343125c698662 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 21:26:47 +0900 Subject: [PATCH 09/16] docs: update fork-join content --- .../.approaches/fork-join/content.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md index 48865caf6..5ecf4bed6 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md @@ -71,24 +71,21 @@ Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting a If there are no strings, a validation step prevents unnecessary processing. A [`ForkJoinPool`][ForkJoinPool] is then created. - The core of [`ForkJoinPool`][ForkJoinPool] is the Fork/Join mechanism, which divides tasks into smaller units and processes them in parallel. -THRESHOLD is the criterion for task division. - -If the range of texts exceeds the THRESHOLD, the task is divided into two subtasks, and [`invokeAll`][invokeAll](leftTask, rightTask) is called to execute both tasks in parallel. - -Each subtask in LetterCountTask will continue calling compute() to divide itself further until the range is smaller than or equal to the threshold. - -For tasks that are within the threshold, letter frequency is calculated. +`THRESHOLD` is the criterion for task division. +If the range of texts exceeds the `THRESHOLD`, the task is divided into two subtasks, and [`invokeAll(leftTask, rightTask)`][invokeAll] is called to execute both tasks in parallel. +Each subtask in LetterCountTask will continue calling compute() to divide itself further until the range is smaller than or equal to the `THRESHOLD`. +For tasks that are within the `THRESHOLD`, letter frequency is calculated. -The [`Character.isAlphabetic`][isAlphabetic] method is used to identify all characters classified as alphabetic in Unicode, covering various languages like English, Korean, Japanese, Chinese, etc., returning true for alphabetic characters and false for numbers, special characters, spaces, and others. +The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning `true`. +Non-alphabetic characters, including numbers, special characters, and spaces, return `false`. -Additionally, since uppercase and lowercase letters are treated as the same character (e.g., A and a), each character is converted to lowercase. +Additionally, since uppercase and lowercase letters are treated as the same character (e.g., `A` and `a`), each character is converted to lowercase. After updating letter frequencies, the final map is returned. [ConcurrentHashMap]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html [ForkJoinPool]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html [isAlphabetic]: https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isAlphabetic-int- -[invokeAll]: https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html +https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html From 72b14855d922bf5a69fba8afca3244df4aea2295 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 21:27:04 +0900 Subject: [PATCH 10/16] docs: update parallel-stream content --- .../.approaches/parallel-stream/content.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md index b64e0a505..e58c23f6b 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md @@ -38,10 +38,10 @@ Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting a If there are no strings to process, a validation step avoids unnecessary computation. To calculate letter frequency, a parallel stream is used. +The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning `true`. +Non-alphabetic characters, including numbers, special characters, and spaces, return `false`. -The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning true. Non-alphabetic characters, including numbers, special characters, and spaces, return false. - -Since we treat uppercase and lowercase letters as the same character (e.g., A and a), characters are converted to lowercase. +Since we treat uppercase and lowercase letters as the same character (e.g., `A` and `a`), characters are converted to lowercase. After updating letter frequencies, the final map is returned. From d876b63274d540434db447c30082f3d4a5f43093 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 21:27:11 +0900 Subject: [PATCH 11/16] docs: update introduction --- .../.approaches/introduction.md | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md index 828651cc5..e00fe09c9 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md @@ -1,32 +1,24 @@ # Introduction There are multiple ways to solve the Parallel Letter Frequency problem. - One approach is to use [`Stream.parallelStream`][stream], and another involves using [`ForkJoinPool`][ForkJoinPool]. ## General guidance To count occurrences of items, a map data structure is often used, though arrays and lists can work as well. - A [`map`][map], being a key-value pair structure, is suitable for recording frequency by incrementing the value for each key. - If the data being counted has a limited range (e.g., characters or integers), an `int[] array` or [`List`][list] can be used to record frequencies. Parallel processing typically takes place in a multi-[`thread`][thread] environment. - -The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the parallelStream() method. - -With parallelStream(), developers can use the ForkJoinPool model for workload division and parallel execution, without the need to manually manage threads or create custom thread pools. +The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the `parallelStream()` method. +With `parallelStream()`, developers can use the [`ForkJoinPool`][ForkJoinPool] model for workload division and parallel execution, without the need to manually manage threads or create custom thread pools. The [`ForkJoinPool`][ForkJoinPool] class, optimized for dividing and managing tasks, makes parallel processing efficient. - -However, parallelStream() uses the common ForkJoinPool by default, meaning multiple parallelStream instances share the same thread pool unless configured otherwise. +However, `parallelStream()` uses the common [`ForkJoinPool`][ForkJoinPool] by default, meaning multiple `parallelStream` instances share the same thread pool unless configured otherwise. As a result, parallel streams may interfere with each other when sharing this thread pool, potentially affecting performance. - Although this doesn’t directly impact solving the Parallel Letter Frequency problem, it may introduce issues when thread pool sharing causes conflicts in other applications. - -Therefore, a custom ForkJoinPool approach is also provided below. +Therefore, a custom [`ForkJoinPool`][ForkJoinPool] approach is also provided below. ## Approach: `parallelStream` @@ -138,8 +130,8 @@ For more information, check the [`fork/join` approach][approach-fork-join]. ## Which approach to use? -When tasks are simple or do not require a dedicated thread pool (such as in this case), the parallelStream approach is recommended. -However, if the work is complex or there is a need to isolate thread pools from other concurrent tasks, the ForkJoinPool approach is preferable. +When tasks are simple or do not require a dedicated thread pool (such as in this case), the `parallelStream` approach is recommended. +However, if the work is complex or there is a need to isolate thread pools from other concurrent tasks, the [`ForkJoinPool`][ForkJoinPool] approach is preferable. [thread]: https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html [stream]: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html From 9ed7813cfc6a4dd4484b5e17775a0db42a4e7236 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 21:34:54 +0900 Subject: [PATCH 12/16] docs: rollback invokeAll --- .../parallel-letter-frequency/.approaches/fork-join/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md index 5ecf4bed6..a532de659 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md @@ -88,4 +88,4 @@ After updating letter frequencies, the final map is returned. [ConcurrentHashMap]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html [ForkJoinPool]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html [isAlphabetic]: https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isAlphabetic-int- -https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html +[invokeAll]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html From 01cbae26b461de48c92b830e6179519f63b12dd6 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 21:36:45 +0900 Subject: [PATCH 13/16] docs: erase whitespace --- .../.approaches/parallel-stream/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md index e58c23f6b..6b532b767 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/parallel-stream/content.md @@ -38,7 +38,7 @@ Using [`ConcurrentHashMap`][ConcurrentHashMap] ensures that frequency counting a If there are no strings to process, a validation step avoids unnecessary computation. To calculate letter frequency, a parallel stream is used. -The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning `true`. +The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning `true`. Non-alphabetic characters, including numbers, special characters, and spaces, return `false`. Since we treat uppercase and lowercase letters as the same character (e.g., `A` and `a`), characters are converted to lowercase. From fbb752584b321b07da12e7a5e034dbddd9396082 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 21:42:39 +0900 Subject: [PATCH 14/16] update introduction.md --- .../parallel-letter-frequency/.approaches/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md index e00fe09c9..283b9461d 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md @@ -7,7 +7,7 @@ One approach is to use [`Stream.parallelStream`][stream], and another involves u To count occurrences of items, a map data structure is often used, though arrays and lists can work as well. A [`map`][map], being a key-value pair structure, is suitable for recording frequency by incrementing the value for each key. -If the data being counted has a limited range (e.g., characters or integers), an `int[] array` or [`List`][list] can be used to record frequencies. +If the data being counted has a limited range (e.g., `Characters` or `Integers`), an `int[] array` or [`List`][list] can be used to record frequencies. Parallel processing typically takes place in a multi-[`thread`][thread] environment. The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the `parallelStream()` method. From ba55162c08b8e661e9f30302475cee771fbd271f Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 23:00:25 +0900 Subject: [PATCH 15/16] docs: clarified that compute is called through invokeAll --- .../parallel-letter-frequency/.approaches/fork-join/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md index a532de659..de2cd7307 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/fork-join/content.md @@ -75,7 +75,7 @@ The core of [`ForkJoinPool`][ForkJoinPool] is the Fork/Join mechanism, which div `THRESHOLD` is the criterion for task division. If the range of texts exceeds the `THRESHOLD`, the task is divided into two subtasks, and [`invokeAll(leftTask, rightTask)`][invokeAll] is called to execute both tasks in parallel. -Each subtask in LetterCountTask will continue calling compute() to divide itself further until the range is smaller than or equal to the `THRESHOLD`. +Each subtask in `LetterCountTask` will continue calling `compute()` (via `invokeAll(leftTask, rightTask)`) to divide itself further until the range is smaller than or equal to the `THRESHOLD`. For tasks that are within the `THRESHOLD`, letter frequency is calculated. The [`Character.isAlphabetic`][isAlphabetic] method identifies all characters classified as alphabetic in Unicode, covering characters from various languages like English, Korean, Japanese, Chinese, etc., returning `true`. From e624a68ccf1b9ee169229f78502b00b4bbf2c297 Mon Sep 17 00:00:00 2001 From: masiljangajji Date: Thu, 14 Nov 2024 23:11:59 +0900 Subject: [PATCH 16/16] docs: parallelStream hyperlink add --- .../parallel-letter-frequency/.approaches/introduction.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md index 283b9461d..8ca8fbf92 100644 --- a/exercises/practice/parallel-letter-frequency/.approaches/introduction.md +++ b/exercises/practice/parallel-letter-frequency/.approaches/introduction.md @@ -10,11 +10,11 @@ A [`map`][map], being a key-value pair structure, is suitable for recording freq If the data being counted has a limited range (e.g., `Characters` or `Integers`), an `int[] array` or [`List`][list] can be used to record frequencies. Parallel processing typically takes place in a multi-[`thread`][thread] environment. -The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the `parallelStream()` method. -With `parallelStream()`, developers can use the [`ForkJoinPool`][ForkJoinPool] model for workload division and parallel execution, without the need to manually manage threads or create custom thread pools. +The Java 8 [`stream`][stream] API provides methods that make parallel processing easier, including the [`parallelStream()`][stream] method. +With [`parallelStream()`][stream], developers can use the [`ForkJoinPool`][ForkJoinPool] model for workload division and parallel execution, without the need to manually manage threads or create custom thread pools. The [`ForkJoinPool`][ForkJoinPool] class, optimized for dividing and managing tasks, makes parallel processing efficient. -However, `parallelStream()` uses the common [`ForkJoinPool`][ForkJoinPool] by default, meaning multiple `parallelStream` instances share the same thread pool unless configured otherwise. +However, [`parallelStream()`][stream] uses the common [`ForkJoinPool`][ForkJoinPool] by default, meaning multiple [`parallelStream`][stream] instances share the same thread pool unless configured otherwise. As a result, parallel streams may interfere with each other when sharing this thread pool, potentially affecting performance. Although this doesn’t directly impact solving the Parallel Letter Frequency problem, it may introduce issues when thread pool sharing causes conflicts in other applications. @@ -130,7 +130,7 @@ For more information, check the [`fork/join` approach][approach-fork-join]. ## Which approach to use? -When tasks are simple or do not require a dedicated thread pool (such as in this case), the `parallelStream` approach is recommended. +When tasks are simple or do not require a dedicated thread pool (such as in this case), the [`parallelStream`][stream] approach is recommended. However, if the work is complex or there is a need to isolate thread pools from other concurrent tasks, the [`ForkJoinPool`][ForkJoinPool] approach is preferable. [thread]: https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html