— Привіт, Аміго!
— Так, тут я, тут.
— Сьогодні я розповім тобі про практичне застосування synchronized.
Коли у програмі багато об'єктів та ниток, то часто трапляються ситуації, коли з одним об'єктом одночасно працює кілька ниток. Нитки при цьому заважають одна одній.
— Так, я це вже знаю.
— Так от, припустимо, у тебе є об'єкт, до якого звертаються кілька ниток. Щоб з ним не було проблем, можна зробити дві речі.
Перша – всі місця роботи з цим об'єктом обернути на блоки synchronized. Але такий підхід може не спрацювати, якщо якийсь програміст у своєму коді звертатиметься до об'єкта безпосередньо, без блоку synchronized.
Тому найчастіше застосовується другий підхід – об'єкт роблять ниткобезпечним (thread-safe). Тобто. механізм synchronized вбудовують у сам об'єкт – оголошують його методи synchronized та/або обертають код усередині методів блоки synchronized.
— Тобто всі об'єкти, які можуть використовуватися з різних ниток, а це майже всі об'єкти програми, я маю зробити thread-safe?
— Загалом, так. Насправді, не всі об'єкти програми використовуються з різних ниток, але зазвичай багато. Отже, коли ти починаєш писати код своєї нитки і в ній звертаєшся до різних об'єктів своєї програми, то при викликі кожного методу, ти повинен задуматися – а чи безпечний цей виклик?
— Безпечний?
— Безпечний (thread-safe) — це безпечно під час виклику з різних ниток.
Ось тобі кілька прикладів. Допустимо, у тебе є об'єкт String, до якого відбувається звернення з різних ниток. Як ти вже повинен був запам'ятати, String (і всі інші типові типи) є immutable. А це означає, що після створення об'єкт не змінюється. Отже, і «зламати» такий об'єкт не можна. Всі immutable об'єкти є thread-safe.
— Вже легше.
— Тепер, припустимо, тобі потрібний рядок, що змінюється.
— Ага, пам'ятаю. Є два види таких рядків – StringBuffer та StringBuilder. StringBuffer - це аналог StringBuilder, але у нього всі методи синхронізовані. Він також є thread-safe?
— Так. Якщо тобі потрібно звертатися до об'єкта StringBuilder з різних ниток, то потрібно замінити його на StringBuffer, інакше рано чи пізно нитки змінюватимуть його одночасно і «поломають».
— А якщо об'єкт, якого відбувається звернення з різних ниток, – це об'єкт мого власного класу? Мені також треба додавати до його методів synchronized?
— Так. Найкраще керуватися таким правилом – усі об'єкти, до яких відбувається звернення з різних ниток, мають бути thread-safe.
— Зрозуміло. Не думав, що так серйозно. Дякую, Еллі.
— Будь ласка. Сподіваюся, ці поради допоможуть тобі, коли Дієго дасть тобі пару своїх легких завдань ☺
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ