Sempre que surge uma pergunta sobre o SO sobre a sincronização Java, algumas pessoas estão ansiosas para apontar que isso synchronized(this)
deve ser evitado. Em vez disso, eles afirmam, é preferível um bloqueio em uma referência privada.
Algumas das razões apresentadas são:
- algum código maligno pode roubar seu bloqueio (muito popular, este também possui uma variante "acidentalmente")
- todos os métodos sincronizados da mesma classe usam exatamente o mesmo bloqueio, o que reduz a taxa de transferência
- você está (desnecessariamente) expondo muita informação
Outras pessoas, inclusive eu, argumentam que synchronized(this)
esse idioma é muito usado (também nas bibliotecas Java), é seguro e bem compreendido. Não deve ser evitado porque você tem um bug e não tem idéia do que está acontecendo no seu programa multithread. Em outras palavras: se for aplicável, use-o.
Estou interessado em ver alguns exemplos do mundo real (nada de foobar) em que this
é preferível evitar um bloqueio quando synchronized(this)
também faria o trabalho.
Portanto: você deve sempre evitá synchronized(this)
-lo e substituí-lo por um cadeado em uma referência particular?
Algumas informações adicionais (atualizadas conforme as respostas):
- estamos falando de sincronização de instância
- implícita (
synchronized
métodos) e forma explícita desynchronized(this)
são consideradas - se você citar Bloch ou outras autoridades sobre o assunto, não deixe de fora as partes de que não gosta (por exemplo, Java efetivo, item sobre Segurança de Thread: Normalmente, é o bloqueio na própria instância, mas há exceções).
- se você precisar de granularidade em seu bloqueio que não seja o
synchronized(this)
fornecido, entãosynchronized(this)
não será aplicável. Portanto, esse não é o problema