Java. Чому локи потрібно тримати якомога менший час?

Збільшення пропускної здатності. Коротший час блокувань може збільшити загальну пропускну здатність системи, оскільки більше потоків може отримати доступ до синхронізованих секцій протягом певного часу.

Реагування на “зовнішні“ події. Коли потоки не чекають довго на доступ до ресурсу через короткі блокування, вони можуть швидше реагувати на зовнішні події. Це може бути критично важливо для систем реального часу або для тих, які мають високі вимоги до часу відгуку(веб-сервери — обробка запитів, бази даних).

Зменшення ризику взаємоблокування. Тримання кількох блокувань одночасно або протягом тривалого часу збільшує ризик взаємоблокувань. Короткі інтервали блокувань мінімізують часове “вікно“, протягом якого інший потік може спробувати отримати блокування в іншому порядку та викликати взаємоблокування.

Прогнозованість та легший дебаг. Системи з довгою тривалістю блокування можуть проявляти непередбачувану поведінку, оскільки важко визначити послідовність операцій у різних потоках(тримання локу “розсинхронізовує/віддаляє“ роботу декількох потоків один від одного). Зберігаючи короткий час блокувань, можна зробити поведінку системи більш прогнозованою та легше її проаналізувати.

Інтерфейс: У додатках з графічним інтерфейсом, довгі блокування можуть призвести до "зависання"(пост про це) або затримок відгуку, що може погіршити враження від користування додатком.


public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(5_000);

        final Object lock = new Object();
        MyThread t1 = new MyThread("My Thread 1", lock);
        MyThread t2 = new MyThread("My Thread 2", lock);

        Thread.sleep(1000);
        System.out.println(t2.getState());
        System.out.println(t1.getState());
    }
}

class MyThread extends Thread {
    private final Object lock;

    public MyThread(String name, Object lock) {
        setName(name);
        this.lock = lock;
        start();
    }

    @Override
    public void run() {
        synchronized (lock) {
            System.out.println("Hello from thread " + getName());
            while (true);
            // довгі обрахунки
        }
        // інша бізнес логіка яку необхідно виконати
    }
}
Результат запуску програми в консолі
Java process profiling. VisualVM

В профайлері бачимо наших два потоки — My Thread 1 і My Thread 2.
Оскільки перший потік запускається першим, він займає лок, другий потік, чекає на цьому лоці нескінченний час і переходить в заблокований стан. Через блокування, код потоку не буде виконано процесором — не буде використано процесорного часу, навідміну від першого потоку.

Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Oleksandr Klymenko
Oleksandr Klymenko@overpathz

Java Software Engineer

2.8KПрочитань
1Автори
53Читачі
На Друкарні з 19 квітня

Більше від автора

  • Java. Повний огляд мережевих моделей. Socket API, forking, non-blocking sockets, event-driven API

    Хоча сокет - це один файловий дескриптор, він є двонаправленим каналом комунікації, який використовується для одночасного відправлення і отримання даних. Операційна система та мережеві протоколи забезпечують управління потоками даних, що дозволяє коректно розрізняти дані

    Теми цього довгочиту:

    Java
  • Java. WebSocket. Spring WebSocket

    Сервер в свою чергу повертає відповідь із 101 статус кодом — що так, давай змінимо протокол між тобою і мною. Тепер будемо використовувати вебсокети. Потім, після з’єднання, я розсилаю всім клієнтам інфомацію про нового користуча (і собі також, не робив додаткових перевірок).

    Теми цього довгочиту:

    Java
  • Телеграм бот. Нотатки. Стаді плани. Архітектура. Вебсокети. Част. 3

    Продовження розробки телеграм бота з попередніх частин. Там ми мінімально налаштовували середовище, а зараз детальніше про саму ідею.

    Теми цього довгочиту:

    Java

Вам також сподобається

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Вам також сподобається