Ответ
Монитором (встроенной блокировкой) для нестатического synchronized метода является экземпляр объекта (this), у которого этот метод вызывается.
Ключевые моменты:
- Каждый объект в Java имеет связанный с ним монитор (intrinsic lock).
- Когда поток входит в
synchronizedметод, он захватывает монитор этого конкретного объекта. - Другие потоки будут заблокированы при попытке войти в любой
synchronizedметод (илиsynchronized(this)блок) этого же экземпляра, пока первый поток не освободит монитор.
Пример:
public class BankAccount {
private int balance;
// Монитором для этого метода служит экземпляр BankAccount
public synchronized void deposit(int amount) {
balance += amount;
}
public synchronized void withdraw(int amount) {
if (balance >= amount) {
balance -= amount;
}
}
}
BankAccount account1 = new BankAccount();
BankAccount account2 = new BankAccount();
// Поток 1: Захватывает монитор account1
account1.deposit(100);
// Поток 2: Может работать с account2 параллельно (это другой монитор).
account2.withdraw(50);
// Поток 3: Будет ждать, если попытается вызвать account1.withdraw() пока Поток 1 не выйдет из deposit().
Эквивалентная запись с явной блокировкой:
public void deposit(int amount) {
synchronized(this) { // Явное указание на монитор объекта
balance += amount;
}
} Ответ 18+ 🔞
Слушай, а вот этот твой вопрос про synchronized методы — это ж классика, блядь! Прям как в том анекдоте про Герасима и Муму, только про потоки. Ну ладно, ща объясню, чтобы у тебя в голове не было как у того немого — «ууууу, блядь».
Так вот, смотри. Когда ты пишешь этот самый synchronized для обычного, нестатического метода, то монитором — этой самой дверью, которую захлопывают, чтобы никто другой не влез — служит сам объект, this, конкретный экземпляр, ёпта!
Представь себе, у тебя есть банковский счёт, BankAccount. Это как Герасим, здоровый мужик, но со своим внутренним замком.
public class BankAccount {
private int balance;
// Монитором для этого метода служит экземпляр BankAccount
public synchronized void deposit(int amount) {
balance += amount; // Положил бабки
}
}
Вот что происходит, когда поток заходит в deposit:
- Поток подходит к объекту
account1и говорит: «Так, Герасим, дай-ка сюда твой монитор, твой внутренний замок». - Захватывает его, блядь! Всё, теперь он хозяин положения.
- Пока он там ковыряется с балансом, любой другой поток, который захочет вызвать ЛЮБОЙ
synchronizedметод этого же самогоaccount1(или залезть вsynchronized(this)блок), будет стоять и ждать, как дурак! Ему скажут: «Муму!», то есть «Пошёл нахуй, монитор занят!». - Как только первый поток выйдет из метода — он отпустит замок. И тогда уже следующий сможет зайти.
А теперь самое интересное, блядь, где многие ебутся! Если у тебя два разных объекта — это как два разных Герасима, у каждого свой замок!
BankAccount account1 = new BankAccount(); // Герасим №1
BankAccount account2 = new BankAccount(); // Герасим №2, совсем другой мужик
// Поток 1: Захватывает монитор account1. Сидит у Герасима №1 в сарае.
account1.deposit(100);
// Поток 2: Ему похуй на Герасима №1! Он спокойно идёт к Герасиму №2 и работает с account2.
account2.withdraw(50); // Никаких проблем, параллельно!
// Поток 3: А вот если он полезет к account1, пока Поток 1 не закончил — вот тут его и накроет, блядь! Будет ждать, как та Муму у озера.
И эта вся магия с synchronized методом — она просто короткая запись, сахар такой, ёпта. Можно сделать то же самое явно, чтоб прям видно было:
public void deposit(int amount) {
synchronized(this) { // Смотри-ка, блядь! Прямо указываю: «Замок — это этот самый объект!»
balance += amount;
}
}
Вот и вся история, блядь. Не надо тут выебываться с какими-то глобальными замками. Каждый объект — сам себе Герасим со своим монитором. Захотел потокам безопасно работать с одним объектом — синхронизируйся по нему. Захотел, чтобы они друг другу не мешали с разными объектами — да похуй, работают параллельно. Главное — не утопить свою Муму в конце, а то совесть замучает, как у Тургенева, блядь.