Структурированный параллелизм организует параллельные процессы контролируемым образом, чтобы облегчить параллельное выполнение. Это предотвращает ситуации гонки, взаимоблокировки и потерянные задания. Структурированный параллелизм может быть реализован на Java с использованием библиотек, фреймворков или экспериментальных инициатив, таких как Project Loom. Концепции и методы структурированного параллелизма в Java:
- ExecutorService и CompletableFuture
- ForkJoinPool и RecursiveTask
ExecutorService и CompletableFuture
ExecutorService в java.util.concurrent управляет пулом рабочих потоков, которые могут выполнять задачи одновременно. CompletableFuture позволяет связывать, управлять и комбинировать задачи. ExecutorService и CompletableFuture обеспечивают систематическое управление параллельными процессами.
Пример:
Java
// Java Program to demonstrate structured concurrency in
// Java using the ExecutorService and CompletableFuture
// classes from the java.util.concurrent package.
import
java.util.concurrent.*;
// Driver class
public
class
StructuredConcurrencyExample {
// function main
public
static
void
main(String[] args)
throws
InterruptedException, ExecutionException
{
ExecutorService executor
= Executors.newFixedThreadPool(
3
);
CompletableFuture<Void> task1
= CompletableFuture.runAsync(() -> {
System.out.println(
"Task 1 started"
);
// Perform task 1
}, executor);
CompletableFuture<Void> task2
= CompletableFuture.runAsync(() -> {
System.out.println(
"Task 2 started"
);
// Perform task 2
}, executor);
CompletableFuture<Void> combinedTasks
= CompletableFuture.allOf(task1, task2);
// Waits for both tasks to complete
combinedTasks.get();
executor.shutdown();
}
}
Выход
Task 1 started Task 2 started
Примечание. Порядок выходных данных задачи может различаться, поскольку задачи выполняются одновременно, а порядок их выполнения может быть разным каждый раз.
ForkJoinPool и RecursiveTask
ForkJoinPool, еще одна среда параллелизма в пакете java.util.concurrent, эффективно выполняет алгоритмы «разделяй и властвуй» и крадет работу. ForkJoinPool с RecursiveTask или RecursiveAction создает организованные параллельные задачи.
Пример:
Java
// Java program to demonstrate the use of the ForkJoinPool
// to create organized concurrent tasks.
import
java.util.concurrent.*;
public
class
StructuredConcurrencyExample {
public
static
void
main(String[] args)
{
ForkJoinPool forkJoinPool =
new
ForkJoinPool();
// Task 1
RecursiveAction task1 =
new
RecursiveAction() {
@Override
protected
void
compute()
{
// Perform task 1
System.out.println(
"Task 1 started"
);
}
};
// Task 2
RecursiveAction task2 =
new
RecursiveAction() {
@Override
protected
void
compute()
{
// Perform task 2
System.out.println(
"Task 2 started"
);
}
};
// Submit both tasks and then join them
ForkJoinTask<Void> submittedTask1
= forkJoinPool.submit(task1);
ForkJoinTask<Void> submittedTask2
= forkJoinPool.submit(task2);
// Wait for both tasks to complete
submittedTask1.join();
submittedTask2.join();
forkJoinPool.shutdown();
}
}
Выход
Task 1 started Task 2 started
Примечание. Порядок выходных данных задачи может различаться, поскольку задачи выполняются одновременно, а порядок их выполнения может быть разным каждый раз.