Ответ
java.util.concurrent (JUC) — это стандартный пакет Java, предоставляющий высокоуровневые, надежные и производительные инструменты для разработки параллельных (многопоточных) приложений. Он был введен в Java 5 для решения сложностей и ошибок, связанных с ручным управлением потоками и низкоуровневой синхронизацией.
Основные компоненты пакета:
-
Executor Framework: Абстракция для управления пулами потоков.
Executor,ExecutorService,ScheduledExecutorService.- Фабрики
Executors(например,newFixedThreadPool,newCachedThreadPool).
-
Потокобезопасные коллекции (Concurrent Collections): Коллекции, оптимизированные для многопоточного доступа без внешней синхронизации.
ConcurrentHashMap,CopyOnWriteArrayList,BlockingQueue.
-
Синхронизаторы (Synchronizers): Утилиты для координации работы потоков.
CountDownLatch— ожидание завершения набора операций.CyclicBarrier— точка сбора для группы потоков.Semaphore— контроль доступа к ограниченному ресурсу.Exchanger— обмен данными между двумя потоками.
-
Атомарные переменные (Atomic Variables): Классы для атомарных операций над одиночными переменными без использования блокировок (на основе
compare-and-swap).AtomicInteger,AtomicLong,AtomicReference.
-
Усовершенствованные механизмы блокировок (Locks): Более гибкая альтернатива ключевому слову
synchronized.ReentrantLock,ReentrantReadWriteLock.Condition— аналог методовwait()/notify()дляLock.
Пример использования ExecutorService:
import java.util.concurrent.*;
public class ExecutorExample {
public static void main(String[] args) {
// Создаем пул из 2 потоков
ExecutorService executor = Executors.newFixedThreadPool(2);
// Отправляем задачи на выполнение
executor.submit(() -> {
String threadName = Thread.currentThread().getName();
System.out.println("Task 1 executed by " + threadName);
});
executor.submit(() -> {
String threadName = Thread.currentThread().getName();
System.out.println("Task 2 executed by " + threadName);
});
// Инициируем упорядоченное завершение (не принимаем новые задачи)
executor.shutdown();
try {
// Ожидаем завершения всех задач (но не более 10 секунд)
if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
executor.shutdownNow(); // Принудительное завершение
}
} catch (InterruptedException e) {
executor.shutdownNow();
}
}
}
Преимущества использования JUC: повышение производительности, уменьшение сложности кода, снижение вероятности ошибок (deadlock, race condition) по сравнению с ручным управлением потоками.