Ответ
Ключевое слово synchronized обеспечивает синхронизацию по монитору (внутреннему замку) объекта.
Правила:
- Нестатический synchronized-метод блокирует монитор объекта
this, на котором вызван метод. - Статический synchronized-метод блокирует монитор объекта класса (
ClassName.class). - Synchronized-блок позволяет явно указать объект-монитор.
Примеры:
public class Counter {
private int count = 0;
private final Object customLock = new Object();
// Синхронизация по монитору объекта 'this'
public synchronized void increment() {
count++;
}
// Синхронизация по монитору класса Counter.class
public static synchronized void staticMethod() {
// ...
}
// Синхронизация по произвольному объекту
public void decrement() {
synchronized (customLock) {
count--;
}
}
}
Важно: Для корректной взаимной блокировки все конкурирующие потоки должны использовать один и тот же объект-монитор.
Ответ 18+ 🔞
А, ну это же про синхронизацию, классика! Сейчас разжуем, как блядь, эту тему про synchronized, чтобы даже у мартышлюшки с бананом в жопе вопросов не осталось.
Смотри, ключевое слово synchronized — это как будто ты на дверь в сортир вешаешь табличку «ЗАНЯТО». Только вместо двери тут монитор (или, проще говоря, внутренний замок) у какого-то объекта. Пока один поток этот замок держит, остальные стоят и бздят в коридоре, ждут своей очереди.
Простые правила, которые надо в печёнках сидеть:
- Обычный
synchronized-метод (не статический). Тут всё просто, как три копейки. Замок вешается на объектthis— то есть на ту самую конкретную контору, у которой этот метод вызвали. Пока один чувак внутри, другие в эту же контору не пролезут. - Статический
synchronized-метод. А вот это уже замок не на конкретную контору, а на целый чертёж завода! То есть на объект класса (Counter.class). Если такой метод выполняется, он блокирует доступ для всех остальных статических синхронизированных методов этого класса, даже если экземпляров (this) дохуя и больше. - Synchronized-блок. Это для самых хитрых жоп. Позволяет не всю дверь на замок закрывать (весь метод), а только сейф в углу. И главное — ты сам выбираешь, на какой именно сейф (объект-монитор) вешаешь замок.
Смотри, как это выглядит в коде, ёпта:
public class Counter {
private int count = 0;
private final Object customLock = new Object(); // Наш личный сейф для замка
// Синхронизация по монитору объекта 'this' (конкретной конторы)
public synchronized void increment() {
count++; // Зашли, сделали дело, вышли, сняли "ЗАНЯТО"
}
// Синхронизация по монитору класса Counter.class (чертёж завода)
public static synchronized void staticMethod() {
// ...
}
// Синхронизация по произвольному объекту (нашему личному сейфу)
public void decrement() {
synchronized (customLock) { // Замок вешаем именно на customLock, а не на всю дверь
count--;
}
}
}
И главное, блядь, запомни, а то пидарасы налетят: Чтобы эта вся хуйня работала и потоки реально ждали друг друга, а не лезли одновременно в одну дырку, они все должны договориться и использовать один и тот же объект-монитор! Это как если у вас один сортир на всех, а табличка «ЗАНЯТО» одна. Если один будет вешать табличку на дверь, а другой — на унитаз, то доверия ебать ноль, и в итоге все обосрутся.