← Назад к вопросам

Что использовал из пакета concurrent

2.0 Middle🔥 211 комментариев
#Многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Пакет java.util.concurrent

Пакет java.util.concurrent — это стандартная библиотека Java для многопоточного программирования. Она предоставляет высокоуровневые инструменты вместо работы с низкоуровневыми потоками и синхронизацией.

1. ExecutorService и Thread Pools

ExecutorService управляет пулом потоков. Вместо создания потоков вручную:

// Плохо: создаём потоки вручную
for (Task task : tasks) {
    new Thread(task).start();
}

// Хорошо: используем ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(10);
for (Task task : tasks) {
    executor.submit(task);
}
executor.shutdown();

Примеры:

  • newFixedThreadPool(n) — пул из n потоков
  • newCachedThreadPool() — динамический пул
  • newSingleThreadExecutor() — один поток
  • newScheduledThreadPool(n) — для планирования

2. Future и Callable

Future позволяет получить результат асинхронного выполнения:

ExecutorService executor = Executors.newFixedThreadPool(1);

Future<Integer> future = executor.submit(new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
        return 42; // результат
    }
});

try {
    Integer result = future.get(); // получаем результат
    System.out.println("Результат: " + result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

3. CountDownLatch

CountDownLatch используется для синхронизации потоков. Один поток ждёт, пока другие потоки завершат работу:

CountDownLatch latch = new CountDownLatch(3); // ждём 3 события

for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        System.out.println(Thread.currentThread().getName() + " начал работу");
        // ... работа ...
        latch.countDown(); // уменьшаем счётчик
    }).start();
}

try {
    latch.await(); // блокируемся до countDown() 3 раза
    System.out.println("Все потоки завершили работу");
} catch (InterruptedException e) {
    e.printStackTrace();
}

4. CyclicBarrier

CyclicBarrier синхронизирует несколько потоков в точке барьера:

CyclicBarrier barrier = new CyclicBarrier(3, () -> {
    System.out.println("Все потоки достигли барьера!");
});

for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        System.out.println(Thread.currentThread().getName() + " ждёт");
        try {
            barrier.await(); // блокируемся
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " продолжает");
    }).start();
}

5. Semaphore

Semaphore ограничивает количество потоков, одновременно получающих доступ к ресурсу:

Semaphore semaphore = new Semaphore(2); // максимум 2 потока

for (int i = 0; i < 5; i++) {
    new Thread(() -> {
        try {
            semaphore.acquire(); // получаем разрешение
            System.out.println(Thread.currentThread().getName() + " работает");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release(); // отпускаем разрешение
        }
    }).start();
}

6. BlockingQueue

BlockingQueue — потокобезопасная очередь, используется для обмена данными между потоками:

BlockingQueue<String> queue = new LinkedBlockingQueue<>();

// Производитель
new Thread(() -> {
    try {
        queue.put("Данные 1");
        queue.put("Данные 2");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}).start();

// Потребитель
new Thread(() -> {
    try {
        String data = queue.take(); // ждёт, если пусто
        System.out.println("Получено: " + data);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}).start();

7. ConcurrentHashMap

ConcurrentHashMap — потокобезопасная версия HashMap:

Map<String, Integer> map = new ConcurrentHashMap<>();

// Несколько потоков могут одновременно писать
for (int i = 0; i < 10; i++) {
    new Thread(() -> {
        map.put("key" + i, i);
    }).start();
}

// Чтение без синхронизации
map.forEach((k, v) -> System.out.println(k + ": " + v));

8. AtomicInteger и AtomicReference

Атомарные операции без синхронизации:

AtomicInteger counter = new AtomicInteger(0);

for (int i = 0; i < 100; i++) {
    new Thread(() -> {
        counter.incrementAndGet(); // потокобезопасно
    }).start();
}

Thread.sleep(1000);
System.out.println("Значение: " + counter.get()); // 100

9. ReentrantLock

ReentrantLock — явная блокировка, более гибкая чем synchronized:

ReentrantLock lock = new ReentrantLock();

new Thread(() -> {
    lock.lock();
    try {
        System.out.println("Критическая секция");
    } finally {
        lock.unlock();
    }
}).start();

10. Condition

Condition работает с ReentrantLock для передачи сигналов между потоками:

ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();

// Поток, ждущий условия
new Thread(() -> {
    lock.lock();
    try {
        condition.await(); // ждёт сигнала
        System.out.println("Сигнал получен");
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}).start();

// Поток, посылающий сигнал
Thread.sleep(1000);
lock.lock();
try {
    condition.signal(); // посылаем сигнал
} finally {
    lock.unlock();
}

Когда использовать

  • ExecutorService — вместо new Thread()
  • CountDownLatch — когда нужно ждать выполнения N событий
  • CyclicBarrier — когда потоки должны встретиться в точке
  • BlockingQueue — для обмена данными между потоками
  • ConcurrentHashMap — вместо synchronized HashMap
  • AtomicInteger — для счётчиков
  • ReentrantLock — вместо synchronized для сложной логики

Пакет java.util.concurrent — это фундамент для написания надёжного многопоточного кода в Java.