Я немного запутался в понимании роли «этого» в синхронизированном блоке. У меня есть некоторое базовое понимание того, для чего используется синхронизированный блок. В статье Этот говорится:
Don’t synchronize on the non-final field on synchronized block because the reference to the non-final field may change anytime and then different threads might synchronize on different objects i.e. no synchronization at all.
Мне непонятно, что это на самом деле означает. Может кто-нибудь, пожалуйста, помогите мне понять, что на самом деле представляет собой это в этом контексте и почему неконечные поля не должны быть синхронизированы в синхронизированном блоке.
(Очень обширное) обсуждение synchronized(this) на stackoverflow.com/questions/442564/…
Насколько мне известно, @Stultuske верен. В java ключевое слово this всегда имеет одно и то же значение и всегда представляет текущий экземпляр этого класса.




this представляет текущий экземпляр этого класса
добавить к ответу; каждый раз, когда вы создаете new экземпляр класса например new Foo(), вы создаете новый экземпляр и получаете ссылку на этот экземпляр. Изнутри класса (если вы находитесь в блоке экземпляра) вы всегда получаете эту ссылку, используя this.
это в java представляет текущий объект или экземпляр так
class TreeNode {
int content;
TreeNode left;
TreeNode right;
public TreeNode(int content, TreeNode left, TreeNode right) {
this.content = content;
this.left = left;
this.right = right;
}
public void setContent(int content) {
synchronized (this) {
this.content = content;
}
}
}
В приведенном выше коде это всегда имеет одно и то же значение: сам экземпляр.
и что касается упомянутой статьи, я понимаю, что не делайте этого:
Class Test{
Student ken = new Student('ken');
public void LockTest() {
synchronized(ken){
doSomething();
}
}
}
поскольку obj не является конечным полем, его можно изменить где-нибудь с помощью ken = new Student('adam'); , в этом случае синхронизация может сначала заблокировать экземпляр Student('ken'),
а затем ссылка на ken уже изменена на экземпляр Student('adam'), другой поток найдет Student('adam') не заблокированным, поэтому перейдите в синхронизированный блок.
так что, возможно, будет много разных блокировок, если вы синхронизировали не окончательные поля.
если мы используем final Student ken = new Student('ken'); синхронизированный (кен), убедитесь, что все потоки пытаются получить одну и ту же блокировку.
Представьте себе обычный туалет с одной дверью. Это так и должно быть. Если кто-то хочет воспользоваться туалетом, вам придется подождать, пока он освободится. А теперь представьте, если бы любой желающий мог добавить свою собственную дверь в туалет, когда бы он ни захотел. Эта система не гарантирует конфиденциальности, не так ли?
Спасибо Ван. @ Амадан, твой пример просто идеален, и это то, что я искал. :-)
у этого есть только одна роль во всем мире Java, и она должна указывать на текущий экземпляр класса, в котором вы находитесь, независимо от того, находится ли он в синхронизированном блоке или нет.