Розширені шаблони роботи з потоками

Оптимізація коду в Java

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Основи пулів потоків

Створення потоків — затратне!

$$

Пули потоків:

  • Повторно використовують наявні потоки
  • Контролюють кількість паралельних потоків
  • Керуються через інтерфейс ExecutorService
Оптимізація коду в Java

Створення пулів потоків

// Фіксований пул із 4 потоків
ExecutorService fixedPool = Executors.newFixedThreadPool(4);


// Кешований пул, що зростає за потреби ExecutorService cachedPool = Executors.newCachedThreadPool();
// Виконавець з одним потоком ExecutorService singleExecutor = Executors.newSingleThreadExecutor();
Оптимізація коду в Java

Надсилання завдань

ExecutorService executor = Executors.newFixedThreadPool(4);

// Надішліть завдання без повернення значення
executor.execute(() -> System.out.println("Simple task"));

// Надішліть завдання з поверненням значення (Callable)
Future<Integer> future = executor.submit(() -> {
    Thread.sleep(1000);
    return 42;
});

// Отримайте результат з Future (блокує до завершення)
int result = future.get();
Оптимізація коду в Java

Зупинка виконавців

// Сигналізуйте про зупинку, але дозвольте поточним завданням завершитись
executor.shutdown();


// Очікуйте завершення (з тайм-аутом) boolean terminated = executor.awaitTermination(5, TimeUnit.SECONDS);
// Примусово зупиніть негайно, скасувавши запущені завдання executor.shutdownNow();
Оптимізація коду в Java

CompletableFuture

  • CompletableFuture
  • Частина API конкурентності Java з Java 8
  • Сучасний підхід до асинхронного програмування
  • Може завершуватись вручну або через Function
  • Дозволяє ланцюжити операції з колбеками
  • Працює з явними пулами потоків або без них
Оптимізація коду в Java

Створення CompletableFuture

// Запустіть асинхронно з виконавцем за замовчуванням
CompletableFuture<Void> runAsync = 
    CompletableFuture.runAsync(() -> performTask());

// Асинхронне постачання з власним виконавцем ExecutorService executor = Executors.newCachedThreadPool(); CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(() -> fetchData(), executor);
Оптимізація коду в Java

Ланцюжки операцій

CompletableFuture<String> future = CompletableFuture
    .supplyAsync(() -> fetchUserData(userId))
    .thenApply(data -> extractUsername(data))
    .exceptionally(ex -> "Unknown user");

// Доступ до результату, коли буде готовий
future.thenAccept(result -> System.out.println(result));
Оптимізація коду в Java

Давайте потренуємось!

Оптимізація коду в Java

Preparing Video For Download...