Skip to content

Commit fe0c471

Browse files
committed
feat(concurrency): 🎸 fork-join, translated
Refers: #8
1 parent ab329fd commit fe0c471

File tree

3 files changed

+110
-114
lines changed

3 files changed

+110
-114
lines changed
Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,36 @@
11
:java-package: src/org/j6toj8/concurrency
22
:section-java-package: ../../../{java-package}
33

4-
=== Framework Fork/Join
4+
=== Fork/Join Framework
55

6-
.Objetivo
6+
.Objective
77
--------------------------------------------------
88
Use the parallel Fork/Join Framework
9-
-
10-
Usar o Framework Fork/Join de paralelismo
119
--------------------------------------------------
1210

13-
Com o framework de Fork/Join é possível dividir uma tarefa grande em pedaços menores e executá-los em paralelo. A utilização do framework é simples. A criação de tarefas quebradas em várias partes pode ser um pouco mais complexa.
11+
With the Fork/Join framework you can split a large task into smaller pieces and execute them in parallel. The use of the framework is simple. Creating broken tasks into several parts can be a bit more complex.
1412

15-
Uma tarefa geralmente segue um comportamento padrão:
13+
A task usually follows a default behavior:
1614

17-
* Recebe um valor;
18-
* Avalia se o valor é pequeno o suficiente para executar a tarefa com ele;
19-
** Caso positivo, executa a tarefa com aquele valor;
20-
** Caso negativo, quebra em uma ou mais partes e cria novas tarefas menores;
21-
* Segue executando de forma recursiva.
15+
* Receives a value;
16+
* Evaluates if the value is small enough to perform the task with it;
17+
** If so, execute the task with that value;
18+
** If not, it breaks into one or more parts and creates new smaller tasks;
19+
* Continues running recursively.
2220

23-
Serão apresentados exemplos utilizando a classe `RecursiveAction`, que não retorna valores, e por isso sua implementação é mais simples. E utilizando a classe `RecursiveTask`, que retorna valores e por isso sua implementação é um pouco mais complexa.
21+
Examples will be presented using the `RecursiveAction` class, which returns no values, so its implementation is simpler. And using the `RecursiveTask` class, which returns values ​​and so its implementation is a bit more complex.
2422

25-
Os exemplos são grandes, pois é necessário implementar toda a classe `RecursiveAction` ou `RecursiveTask` para o exemplo funcionar. Por isso, os passos serão descritos com comentários no código, explicando o funcionamento de cada chamada realizada ao framework.
23+
The examples are large because you need to implement the entire `RecursiveAction` or `RecursiveTask` class for the example to work. Therefore, the steps will be described with comments in the code, explaining the operation of each call made to the framework.
2624

27-
. É possível implementar uma `RecursiveAction` que divide uma tarefa grande em partes menores.
25+
. You can implement a `RecursiveAction` that divides a large task into smaller parts.
2826
+
2927
[source,java,indent=0]
3028
.{java-package}/forkjoin/ForkJoin_RecursiveAction.java
3129
----
3230
include::{section-java-package}/forkjoin/ForkJoin_RecursiveAction.java[tag=code]
3331
----
3432
+
35-
.Saída no console
33+
.console output
3634
[source,console]
3735
----
3836
ForkJoinPool-1-worker-1 - ABCDEF
@@ -41,23 +39,23 @@ ForkJoinPool-1-worker-2 - NOPQRS
4139
ForkJoinPool-1-worker-3 - GHIJKLM
4240
----
4341
+
44-
.. Esse exemplo cria uma tarefa do tipo `RecursiveAction` chamada `ImpressaoDeStrings`.
45-
.. Essa `RecursiveAction` recebe uma `String` para imprimir no Console.
46-
.. No método `compute`, a tarefa decide se irá imprimir diretamente no console, ou se irá dividir esse trabalho em duas partes: caso a `String` tenha menos que 10 caracteres, ela imprime diretamente no Console; caso contrário, divide o trabalho em duas novas tarefas.
42+
.. This example creates a task of type `RecursiveAction` called `StringPrinting`.
43+
.. This `RecursiveAction` gets a `String` to print to the Console.
44+
.. In the `compute` method, the job decides whether to print directly to the console, or to split this job into two parts: if the `String` is less than 10 characters long, it prints directly to the console; otherwise it splits the work into two new tasks.
4745
+
48-
Perceba que cada impressão no console é realizada em uma _thread_ diferente, ficando claro que o trabalho está sendo compartilhado por múltiplas _threads_.
46+
Note that each print on the console is performed on a different _thread_, making it clear that the job is being shared by multiple _threads_.
4947
+
50-
Perceba também que o processamento da String não retorna nenhum valor, e por isso foi utilizada a classe `RecursiveAction`.
48+
Also note that String processing returns no value, so the `RecursiveAction` class was used.
5149

52-
. Caso seja necessário retornar um valor, é possível implementar uma `RecursiveTask` que divide uma tarefa grande em partes menores.
50+
. If you need to return a value, you can implement a `RecursiveTask` that divides a large task into smaller parts.
5351
+
5452
[source,java,indent=0]
5553
.{java-package}/forkjoin/ForkJoin_RecursiveTask.java
5654
----
5755
include::{section-java-package}/forkjoin/ForkJoin_RecursiveTask.java[tag=code]
5856
----
5957
+
60-
.Saída no console
58+
.console output
6159
[source,console]
6260
----
6361
ForkJoinPool-1-worker-3 - NOPQRS
@@ -67,21 +65,21 @@ ForkJoinPool-1-worker-1 - TUVWXYZ
6765
Resultado da execução: 26
6866
----
6967
+
70-
.. Esse exemplo cria uma tarefa do tipo `RecursiveTask` chamada `ImpressaoDeStrings`.
71-
.. Essa `RecursiveTask` recebe uma `String` para imprimir no Console.
72-
.. No método `compute`, a tarefa decide se irá imprimir diretamente no console, ou se irá dividir esse trabalho em duas partes: caso a `String` tenha menos que 10 caracteres, ela imprime diretamente no Console; caso contrário, divide o trabalho em duas novas tarefas.
68+
.. This example creates a task of type `RecursiveTask` called `StringPrinting`.
69+
.. This `RecursiveTask` is given a `String` to print to the Console.
70+
.. In the `compute` method, the job decides whether to print directly to the console, or to split this job into two parts: if the `String` is less than 10 characters long, it prints directly to the console; otherwise it splits the work into two new tasks.
7371
+
74-
Perceba também que o processamento da String retorna quantos caracteres foram impressos, e por isso foi utilizada a classe `RecursiveTask`.
75-
72+
Also note that String processing returns how many characters were printed, so the `RecursiveTask` class was used.
7673

74+
.References
7775
****
7876
7977
* Managing Concurrent Processes
8078
+
81-
Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 377). Wiley. Edição do Kindle.
79+
Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 377). Wiley. Kindle Edition.
8280
8381
* https://www.baeldung.com/java-fork-join[Guide to the Fork/Join Framework in Java.]
8482
8583
* https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html[Fork/Join.] The Java™ Tutorials.
8684
87-
****
85+
****

src/org/j6toj8/concurrency/forkjoin/ForkJoin_RecursiveAction.java

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,58 +9,57 @@
99
public class ForkJoin_RecursiveAction {
1010

1111
// tag::code[]
12-
// Classe que representa a tarefa que será executada
13-
static class ImpressaoDeStrings extends RecursiveAction {
12+
// Class that represents the task that will be performed
13+
static class StringPrinterAction extends RecursiveAction {
1414

15-
private String stringParaImprimir; // String que será impressa
15+
private String stringToPrint;
1616

17-
public ImpressaoDeStrings(String stringParaImprimir) {
18-
this.stringParaImprimir = stringParaImprimir;
17+
public StringPrinterAction(String stringToPrint) {
18+
this.stringToPrint = stringToPrint;
1919
}
2020

2121
@Override
2222
protected void compute() {
23-
if (stringParaImprimir.length() < 10) {
24-
// se a String tiver menos de 10 caracteres, será impressa
25-
System.out.println(Thread.currentThread().getName() + " - " + stringParaImprimir);
23+
if (stringToPrint.length() < 10) {
24+
// if String is less than 10 characters, will print
25+
System.out.println(Thread.currentThread().getName() + " - " + stringToPrint);
2626
} else {
27-
// caso contrário, são criadas duas novas tarefas, uma com a primeira metade da String
28-
// e outra com a segunda metade da String
29-
List<ImpressaoDeStrings> novasTarefas = divideEmDuasTarefas();
30-
31-
// Invoca a execução das duas tarefas criadas
32-
ForkJoinTask.invokeAll(novasTarefas);
27+
// otherwise, two new tasks are created, one with the first half of String and one with the second half of String
28+
List<StringPrinterAction> newTasks = divideInTwoTasks();
29+
30+
// Invoke execution of two created tasks
31+
ForkJoinTask.invokeAll(newTasks);
3332
}
3433
}
3534

36-
private List<ImpressaoDeStrings> divideEmDuasTarefas() {
37-
// esse método divide a String em duas partes e cria duas novas tarefas
38-
// cada uma das tarefas recebe uma parte da String
35+
private List<StringPrinterAction> divideInTwoTasks() {
36+
// this method splits the string into two parts and creates two new tasks
37+
// each task gets a part of the String
3938

40-
int tamanhoDaString = stringParaImprimir.length();
41-
int meioDaString = tamanhoDaString / 2;
39+
int stringSize = stringToPrint.length();
40+
int stringMiddle = stringSize / 2;
4241

43-
String primeiraMetade = stringParaImprimir.substring(0, meioDaString);
44-
String segundaMetade = stringParaImprimir.substring(meioDaString);
42+
String firstHalf = stringToPrint.substring(0, stringMiddle);
43+
String secondHalf = stringToPrint.substring(stringMiddle);
4544

46-
List<ImpressaoDeStrings> acoes = new ArrayList<ImpressaoDeStrings>();
47-
acoes.add(new ImpressaoDeStrings(primeiraMetade));
48-
acoes.add(new ImpressaoDeStrings(segundaMetade));
49-
return acoes;
45+
List<StringPrinterAction> actions = new ArrayList<StringPrinterAction>();
46+
actions.add(new StringPrinterAction(firstHalf));
47+
actions.add(new StringPrinterAction(secondHalf));
48+
return actions;
5049
}
5150

5251
}
5352

5453
public static void main(String[] args) {
55-
// string que queremos imprimir
56-
String stringParaImprimir = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
57-
58-
// tarefa principal que será executada
59-
ImpressaoDeStrings tarefa = new ImpressaoDeStrings(stringParaImprimir);
60-
61-
// criação do ForkJoinPool e execução da tarefa
54+
// string we want to print
55+
String stringToPrint= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
56+
57+
// main task to be performed
58+
StringPrinterAction task = new StringPrinterAction(stringToPrint);
59+
60+
// ForkJoinPool creation and task execution
6261
ForkJoinPool forkJoinPool = new ForkJoinPool();
63-
forkJoinPool.invoke(tarefa);
62+
forkJoinPool.invoke(task);
6463
}
6564
// end::code[]
6665

src/org/j6toj8/concurrency/forkjoin/ForkJoin_RecursiveTask.java

Lines changed: 51 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,79 +4,78 @@
44
import java.util.List;
55
import java.util.concurrent.ForkJoinPool;
66
import java.util.concurrent.ForkJoinTask;
7-
import java.util.concurrent.RecursiveAction;
87
import java.util.concurrent.RecursiveTask;
98

109
public class ForkJoin_RecursiveTask {
1110

1211
// tag::code[]
13-
// Classe que representa a tarefa que será executada
14-
static class ImpressaoDeStrings extends RecursiveTask<Integer> {
12+
// Class that represents the task that will be performed
13+
static class StringPrinter extends RecursiveTask<Integer> {
1514

16-
private String stringParaImprimir; // String que será impressa
15+
private String stringToPrint;
1716

18-
public ImpressaoDeStrings(String stringParaImprimir) {
19-
this.stringParaImprimir = stringParaImprimir;
17+
public StringPrinter(String stringToPrint) {
18+
this.stringToPrint = stringToPrint;
2019
}
2120

2221
@Override
2322
protected Integer compute() {
24-
if (stringParaImprimir.length() < 10) {
25-
// se a String tiver menos de 10 caracteres, será impressa
26-
System.out.println(Thread.currentThread().getName() + " - " + stringParaImprimir);
27-
28-
// retornamos a quantidade de caracteres impressos
29-
return stringParaImprimir.length();
23+
if (stringToPrint.length() < 10) {
24+
// if String is less than 10 characters, will print
25+
System.out.println(Thread.currentThread().getName() + " - " + stringToPrint);
26+
27+
// return the amount of characters printed
28+
return stringToPrint.length();
3029
} else {
31-
// caso contrário, são criadas duas novas tarefas, uma com a primeira metade da String
32-
// e outra com a segunda metade da String
33-
List<ImpressaoDeStrings> novasTarefas = divideEmDuasTarefas();
34-
ImpressaoDeStrings tarefa1 = novasTarefas.get(0);
35-
ImpressaoDeStrings tarefa2 = novasTarefas.get(1);
36-
37-
// 'fork' irá enviar a tarefa1 para ser executada em uma nova thread
38-
ForkJoinTask<Integer> primeiraTarefa = tarefa1.fork();
39-
40-
// 'compute' irá executar a tarefa2 nessa mesma thread
41-
Integer resultadoDaTarefa2 = tarefa2.compute();
42-
43-
// 'join' irá pegar o resultado da tafera1 que estava sendo executada em outra thread
44-
Integer resultadoDaTarefa1 = primeiraTarefa.join();
45-
46-
// retornamos a soma dos resultados, pois é a quantidade de carateres impressos
47-
return resultadoDaTarefa2 + resultadoDaTarefa1;
30+
// otherwise, two new tasks are created, one with the first half of String and one with the second half of String
31+
List<StringPrinter> newTasks = divideInTwoTasks();
32+
StringPrinter task1 = newTasks.get(0);
33+
StringPrinter task2 = newTasks.get(1);
34+
35+
// 'fork' will send task1 to run on a new thread
36+
ForkJoinTask<Integer> firstTask = task1.fork();
37+
38+
// 'compute' will execute task2 on this same thread
39+
Integer taskResult2 = task2.compute();
40+
41+
// 'join' will get the result of task1 that was running on another thread
42+
Integer taskResult1 = firstTask.join();
43+
44+
// return the sum of the results because it is the number of characters printed
45+
return taskResult2 + taskResult1;
4846
}
4947
}
5048

51-
private List<ImpressaoDeStrings> divideEmDuasTarefas() {
52-
// esse método divide a String em duas partes e cria duas novas tarefas
53-
// cada uma das tarefas recebe uma parte da String
54-
55-
int tamanhoDaString = stringParaImprimir.length();
56-
int meioDaString = tamanhoDaString / 2;
57-
58-
String primeiraMetade = stringParaImprimir.substring(0, meioDaString);
59-
String segundaMetade = stringParaImprimir.substring(meioDaString);
60-
61-
List<ImpressaoDeStrings> acoes = new ArrayList<ImpressaoDeStrings>();
62-
acoes.add(new ImpressaoDeStrings(primeiraMetade));
63-
acoes.add(new ImpressaoDeStrings(segundaMetade));
64-
return acoes;
49+
private List<StringPrinter> divideInTwoTasks() {
50+
// this method splits the string into two parts and creates two new tasks
51+
// each task gets a part of the String
52+
53+
int stringSize = stringToPrint.length();
54+
int stringMiddle = stringSize / 2;
55+
56+
String firstHalf = stringToPrint.substring(0, stringMiddle);
57+
String secondHalf = stringToPrint.substring(stringMiddle);
58+
59+
List<StringPrinter> actions = new ArrayList<StringPrinter>();
60+
actions.add(new StringPrinter(firstHalf));
61+
actions.add(new StringPrinter(secondHalf));
62+
return actions;
6563
}
6664

6765
}
6866

6967
public static void main(String[] args) {
70-
// string que queremos imprimir
71-
String stringParaImprimir = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
72-
73-
// tarefa principal que será executada
74-
ImpressaoDeStrings tarefa = new ImpressaoDeStrings(stringParaImprimir);
75-
76-
// criação do ForkJoinPool e execução da tarefa
68+
// string we want to print
69+
String stringToPrint= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
70+
71+
// main task to be performed
72+
StringPrinter task = new StringPrinter(stringToPrint);
73+
74+
// ForkJoinPool creation and task execution
7775
ForkJoinPool forkJoinPool = new ForkJoinPool();
78-
Integer resultado = forkJoinPool.invoke(tarefa);
79-
System.out.println("Resultado da execução: " + resultado);
76+
Integer result = forkJoinPool.invoke(task);
77+
System.out.println("Execution result: " + result);
78+
8079
}
8180
// end::code[]
8281

0 commit comments

Comments
 (0)