📌 Что такое
Ключевое слово
✔️ Основные особенности:
1️⃣ Обеспечивает чтение переменной из основной памяти, а не из кэша потока.
2️⃣ Гарантирует видимость изменений между потоками.
Пример:
💡 Ограничение:
#java #volatile #multithreading
volatile и как оно работает?Ключевое слово
volatile в Java используется для переменных, к которым обращаются несколько потоков. Оно гарантирует, что изменения переменной одним потоком будут видны другим.1️⃣ Обеспечивает чтение переменной из основной памяти, а не из кэша потока.
2️⃣ Гарантирует видимость изменений между потоками.
Пример:
class SharedObject {
volatile int count = 0;
}volatile не гарантирует атомарность операций. Для этого используйте synchronized или классы из java.util.concurrent.#java #volatile #multithreading
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤1🔥1
synchronized?Ключевое слово
synchronized используется для управления доступом к разделяемым ресурсам в многопоточном окружении.📌 Пример использования:
1️⃣ Синхронизация метода:
public synchronized void increment() {
count++;
}2️⃣ Синхронизация блока кода:
public void increment() {
synchronized (this) {
count++;
}
}• Обеспечивает монопольный доступ к методу или блоку.
• Снижает производительность из-за блокировок.
synchronized только там, где это действительно необходимо, чтобы избежать узких мест.#java #synchronized #multithreading
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤1
ExecutorService и ForkJoinPoolОба механизма предназначены для работы с многопоточностью, но у них разные задачи:
• ExecutorService – управляет пулом потоков, подходит для выполнения Runnable и Callable.• ForkJoinPool – оптимизирован для рекурсивных задач, использует алгоритм work-stealing.ExecutorService:
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(() -> System.out.println("Task executed"));
executor.shutdown();
ForkJoinPool:
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
class SumTask extends RecursiveTask<Integer> {
private final int[] array;
private final int start, end;
private final int threshold = 10;
public SumTask(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
if (end - start <= threshold) {
// Базовый случай: небольшая задача
int sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
} else {
// Разделяем задачу
int mid = (start + end) / 2;
SumTask leftTask = new SumTask(array, start, mid);
SumTask rightTask = new SumTask(array, mid, end);
leftTask.fork(); // Асинхронно запускаем левую подзадачу
int rightResult = rightTask.compute(); // Синхронно вычисляем правую подзадачу
int leftResult = leftTask.join(); // Ждем завершения левой подзадачи
return leftResult + rightResult;
}
}
}
public class ForkJoinExample {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
SumTask task = new SumTask(array, 0, array.length);
int result = pool.invoke(task);
System.out.println("Сумма: " + result);
}
}
ForkJoinPool динамически управляет количеством потоков, при необходимости создавая новые. Обычно это количество соответствует числу процессоров, доступных в системе.
ForkJoinPool для рекурсивных задач, а ExecutorService – для классической многопоточности.#java #executorservice #forkjoinpool #multithreading
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤4🔥1👏1