У прикладі methodA і methodB є методами екземпляра (на відміну від статичних методів). Введення synchronized
методу екземпляра означає, що потік повинен придбати замок ("внутрішній замок") на об'єктному екземплярі, до якого використовується метод, перш ніж потік може почати виконувати будь-який код у цьому методі.
Якщо у вас є два різні методи екземпляра, позначені синхронізованими, і різні потоки викликають ці методи одночасно на одному об'єкті, ці потоки будуть претендувати на один і той же замок. Як тільки один потік отримує блокування, всі інші потоки вимикаються з усіх методів синхронізованого примірника на цьому об'єкті.
Для того, щоб обидва способи працювали одночасно, їм довелося б використовувати різні блокування, наприклад:
class A {
private final Object lockA = new Object();
private final Object lockB = new Object();
public void methodA() {
synchronized(lockA) {
//method A
}
}
public void methodB() {
synchronized(lockB) {
//method B
}
}
}
де синтаксис синхронізованого блоку дозволяє вказати конкретний об'єкт, якому виконавчий потік повинен придбати внутрішній замок, щоб увійти до блоку.
Важливо розуміти, що хоча ми ставимо "синхронізоване" ключове слово за окремими методами, основна концепція - це внутрішній замок за лаштунками.
Ось як у підручнику Java описуються відносини:
Синхронізація побудована навколо внутрішньої сутності, відомої як внутрішній замок або замок монітора. (Специфікація API часто посилається на цю сутність просто як "монітор".) Внутрішні блокування відіграють певну роль в обох аспектах синхронізації: забезпечення виключного доступу до стану об'єкта та встановлення взаємозв'язків, що мають місце перед важливістю для видимості.
Кожен об’єкт має властивий йому замок. За умовою, потік, який потребує ексклюзивного та послідовного доступу до полів об'єкта, повинен отримати власний замок об'єкта перед доступом до них, а потім випустити внутрішній замок, коли це зроблено з ними. Кажуть, що нитка володіє власним замком між часом, коли вона придбала замок і відпустила замок. Поки нитка володіє внутрішнім замком, жодна інша нитка не може придбати такий самий замок. Інший потік блокується при спробі придбати замок.
Мета блокування - захист спільних даних. Ви б використовували окремі блокування, як показано в наведеному вище прикладі коду, лише якщо кожен замок захищав різні члени даних.