Мутація в потоках

текст перекладу
Кілька потоків можуть виконуватись паралельно в комп'ютері. Ці потоки можуть одночасно отримувати доступ до однакових ресурсів пам'яті та змінювати їх значення. Така ситуація, коли кілька потоків отримують доступ та змінюють одне й те ж ресурс пам'яті або змінну, називається мутацією.

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

Умова гонки (Race Condition)

Припустимо, у нас є два потоки T1 та T2. Потік T1 читає значення змінної count, збільшує його на 1 та записує результат, в той час як потік T2 читає значення змінної count та зменшує його на 1.

Потоки T1 та T2 виконуються одночасно, припустимо, що початкове значення count становить 10.

T1 читає змінну count (count = 10);

Припустимо, що потік T1 призупиняється, і починає виконуватись потік T2

T2 читає змінну count (count = 10);

Тепер потік T2 призупиняється, і потік T1 відновлюється

T1 збільшує count на 1 та записує зміни (count = 11);

Тепер T2 продовжує виконання

T2 зменшує count на 1 (count = 10) та записує зміни (count = 9);

У цій ситуації зміни, зроблені потоком T1, втрачаються. У даному прикладі кінцеве значення count залежить від порядку виконання потоків.

Така умова, коли результат залежить від послідовності виконання потоків, називається умовою гонки (Race Condition).

Дедлок (Deadlock)

Припустимо, що потік чекає на подію, яка ніколи не відбудеться, така ситуація призводить до дедлоку, при якому потік буде нескінченно чекати на подію.

Критична секція (Critical Section):

Частина коду, яка призводить до умови гонки, називається критичною секцією. Іншими словами, критична секція — це частина коду, яка отримує доступ до спільних ресурсів.

Щоб вирішити проблеми мутації, необхідно забезпечити, щоб лише один потік міг отримати доступ до критичної секції одночасно. Це можна досягти різними способами:

  1. за допомогою mutex lock
  2. синхронізованих методів
  3. синхронізованих блоків

Використання mutex lock:

Під час доступу до спільної змінної можна використовувати mutex lock. Перед доступом до змінної ми отримуємо блокування. Тепер, коли інший потік намагається отримати доступ до блокування, він змушений чекати, поки перший потік не звільнить блокування. Таким чином, mutex lock забезпечує, що лише один потік може отримати доступ до критичної секції одночасно.

Синхронізовані методи (Synchronized Methods):

Щоб забезпечити, що лише один потік може отримати доступ до критичної секції одночасно, ми можемо використовувати синхронізовані методи.

Синтаксис:

public synchronized void function(){  
 //критична секція  
}

Використання ключового слова synchronized у визначенні методу Java гарантує, що лише один потік може отримати доступ до цього методу одночасно.

Синхронізований блок (Synchronized Block):

Ми можемо визначити синхронізований блок всередині методу, щоб забезпечити, що лише один потік може отримати доступ до критичної секції.

Синтаксис:

public void function{  
 synchronized(this){  
 //критична секція  
 }  
}

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

Ця стаття пояснила проблеми мутації з потоками в Java та деякі рішення для цих проблем. Існує багато рішень для таких проблем. Є ще багато чого, що можна досліджувати в Java.

Продовжуй кодити…

Перекладено з: Mutation in Threads

Leave a Reply

Your email address will not be published. Required fields are marked *