4
respostas

Dúvida - Exercício 3 da aula 6 - Threads

Se eu utilizar o synchronized em um método, ele faz isso...

synchronized (this)

Ou seja, nessa caso estaremos passando o objeto atual para o synchronized.

No caso do exercício, apenas sincronizamos o atributo mensagens de uma instância de ProduzMensagens, porém referenciamos ele como mensagens e não como this.mensagens.

synchronized (this.mensagens) {
    this.mensagens.add("Mensagem " + i);
}

Tem diferença para o synchronized ?

4 respostas

Fala aí Laércio blz?

Quando você diz usar o synchronized em um método está se referindo isso:

public synchronized void meuMetodo() {
}

?

Isso.

Certo,

Vamos supor que temos uma classe MinhaClasse, existem 3 formas de utilizar o synchronized:

  1. Método de instancia

     public void synchronized meuMétodo(){
     }
    • Nesse caso o bloqueio (sincronismo) é feito na instancia (ou seja duas ou mais threads nunca podem invocar esse método para a mesma instancia simultaneamente. Em instancias diferentes pode ser invocado simultaneamente. )
  2. Método estático

     public static synchronized void meuMetodoEstatico(){
     }
    • Nesse caso o bloqueio é feito na classe (ou seja somente uma thread por vez pode invocar esse método.)
  3. Bloco sincronizado

     public void meuMetodo(){
         synchronized(umObjeto){
         }
     }
    • Nesse caso vai depender do objeto que for passado para o synchronized ser for this ou um atributo de instancia o bloqueio é feito por instancia (equivalente ao exemplo de 1), se for passado um atributo estático o bloqueio é feito na classe (equivalente ao exemplo 2). A vantagem dessa abordagem é que você pode deixar somente trechos do seu código sincronizados e não um método inteiro ou a classe inteira.

Espero ter ajudado!

Fernando, obrigado pela ajuda...

O cenário (na verdade o proposto no exercício) é parecido com seu exemplo 3.

O que me gerou dúvida é porque o instrutor não usou o this para o atributo mensagens.

synchronized (mensagens) {
    mensagens.add("Mensagem " + i);
}

Tenho costume de usar this para deixar claro que determinado atributo é do objeto e não do método .

Rodei o código abaixo e deu o mesmo resultado do acima. Ou seja, funcionou thread-safe.

synchronized (this.mensagens) {
    this.mensagens.add("Mensagem " + i);
}

Com base em sua excelente explicação e em ambos os casos ele bloqueou só o atributo mensagens dessa instância?