Збільшення пропускної здатності. Коротший час блокувань може збільшити загальну пропускну здатність системи, оскільки більше потоків може отримати доступ до синхронізованих секцій протягом певного часу.
Реагування на “зовнішні“ події. Коли потоки не чекають довго на доступ до ресурсу через короткі блокування, вони можуть швидше реагувати на зовнішні події. Це може бути критично важливо для систем реального часу або для тих, які мають високі вимоги до часу відгуку(веб-сервери — обробка запитів, бази даних).
Зменшення ризику взаємоблокування. Тримання кількох блокувань одночасно або протягом тривалого часу збільшує ризик взаємоблокувань. Короткі інтервали блокувань мінімізують часове “вікно“, протягом якого інший потік може спробувати отримати блокування в іншому порядку та викликати взаємоблокування.
Прогнозованість та легший дебаг. Системи з довгою тривалістю блокування можуть проявляти непередбачувану поведінку, оскільки важко визначити послідовність операцій у різних потоках(тримання локу “розсинхронізовує/віддаляє“ роботу декількох потоків один від одного). Зберігаючи короткий час блокувань, можна зробити поведінку системи більш прогнозованою та легше її проаналізувати.
Інтерфейс: У додатках з графічним інтерфейсом, довгі блокування можуть призвести до "зависання"(пост про це) або затримок відгуку, що може погіршити враження від користування додатком.
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);
// довгі обрахунки
}
// інша бізнес логіка яку необхідно виконати
}
}
В профайлері бачимо наших два потоки — My Thread 1 і My Thread 2.
Оскільки перший потік запускається першим, він займає лок, другий потік, чекає на цьому лоці нескінченний час і переходить в заблокований стан. Через блокування, код потоку не буде виконано процесором — не буде використано процесорного часу, навідміну від першого потоку.