Threads(synchronized)

3 respostas
G

Na sincronização de threads exite uma palavra reservada chamada synchronized que faz a sincronização de threads a sintaxe dela é:

public synchronized void t(){}

ou

void t(){synchronized(Object){}}

O sincronismo de threads aceita qualquer tipo de objeto desde string ate inteiros? Para que serve este objeto no sincronismo? Eu to estudando pra certificação e não to entendendo muito a respeito disso. Mais uma coisa porque a palavra synchronized tem que vir antes de void?
Alguem poderia explicar mais ou menos isto? Grato.

[size=“9”][color=“red”]Editado: Cassolato
Topico movido : Certificacao
[/color][/size]

3 Respostas

B

Ola gollun,

“gollun”:
Na sincronização de threads exite uma palavra reservada chamada synchronized que faz a sincronização de threads a sintaxe dela é:

public synchronized void t(){}

ou

void t(){synchronized(Object){}}

O sincronismo de threads aceita qualquer tipo de objeto desde string ate inteiros?


Para a sincronização de de objetos, só serve objetos, não primitivos.

“gollun”:

Para que serve este objeto no sincronismo?

No caso, quando a sincronização está em um objeto, ele só é acessado por um “chamador” por vez, deste modo se evita corrompe-lo, por exemplo um java.util.Vector, que tem os metodos sincronizados, então, se vc quer uma coleção para trafegar em varios metodos, mas quer garantir que todos tenham uma informação um pouco mais confiável, use ele…

“gollun”:

Mais uma coisa porque a palavra synchronized tem que vir antes de void?

Todo modificador de metodo, assim como static, native e synchronized tem que vir antes da declaração do tipo de retorno, por definição e para não confundir, pois se pudesse vir depois daria a impressão que eles servem para o que será retornado… vê se vc não acharia estranho encontrar algo assim:

BrunoBastosPJ

Um blocko synchronized aceita um Object como parâmetro, e como tudo em java é um Object ( em java 5 int, float são convertidos implicitamente). Quando você sincroniza um objeto você “trava” o acesso a esse objeto por várias threads. Por exemplo uma transação com banco de dados, deve ser sincronizada. Não seria ruim se enquanto você estivesse inserindo uma informação importante em um banco, alguem estivesse consultando ao mesmo tempo, e não pegasse essa informação?

ela tem que vir antes do void, do mesmo jeito que a palavra class tem que vir antes do nome da classe, na declaração. do mesmo jeito que o tipo de uma variável de instância (String, int ou qualquer outro objeto) tem que vir antes do nome dela hehehehe.

se você tem 2 métodos sincronizados, por exemplo

public synchronized void addInDB(String name) { }

public synchronized String[] getInDB() { }

Uma instância dessa classe , mesmo que esteja em 2 threads diferentes, só vai poder chamar um método por vez. A sincronização bloqueia o objeto, se você chamar o método addInDB, você só vai conseguir chamar o método getInDB depois que o primeiro tiver terminado.

Para a certificação você tem que entender que a sincronização de métodos não estáticos é feito por INSTÂNCIA!! Uma instância A não pode chamar o 2 metodos ao mesmo tempo, porém uma instância B pode chamar qualquer 1 dos método ao mesmo tempo que A.

Já na sincronização de métodos staticos, só um pode ser chamado, pois staticos pertencem a classe, não as instâncias.

Procure por “buracos negos”, eu tirei 62% nessa parte na minha certificação, só lembrar dos buracos negros, quando olhei a nota da prova hehehehe por sorte eu consegui passar =)

J

Exemplo de uso de sincronização (clássico, faço isso toda vez :lol: ).

Aplicação de banco.

public class Conta{
   private Double saldo;

   public boolean sacar(double quantia){
      if(saldo.doubleValue()>=quantia){
         saldo = Double.valueOf(saldo.doubleValue()-quantia);
         return true;
      }
      return false;
   }

   public void depositar(double quantia){
      saldo = Double.valueOf(saldo.doubleValue()+quantia);
   }
}

Agora imagine que João e Maria tem uma conta conjunta, cada um tem um cartão e pode executar saques e depósitos individualmente.

O saldo da conta deles é de R$ 1.000,00.

Maria vai ao caixa eletrônico para sacar R$ 600,00, ao digitar os dados o servidor inicia uma Thread para realizar o saque.

João chega ao mesmo tempo em outro caixa eletrônico para fazer um saque de R$ 500,00, ao digitar os dados o servidor inicia uma Thread para realizar o saque.

Agora o servidor tem 2 Threads para usar o mesmo objeto Conta que o servidor tem em memória...

A Thread de Maria começa a executar primeiro, executa o if e verifica se o saldo é maior ou igual a quantia a ser sacada, como o saldo é de R$ 1.000,00 e a quantia é de R$ 600,00 entra no if para subtrair o valor do saldo, mas antes de subtrair o sistema operacional pára a Thread de Maria para executar a de João...

A Thread de João começa a executar, executa o if e verifica se o saldo é maior ou igual à quantia a ser sacada, como o saldo é de R$ 1.000,00 (lembre-se que a Thread de Maria parou antes de subtrair) e a quantia é R$ 500,00 entra no if e subtrai o valor do saldo, retorna true e o caixa eletrônico libera o dinheiro... A Thread de João morre...

A Thread de Maria volta a executar de onde parou, subtrai os R$ 600,00 do saldo e retorna true, o caixa eletrônico então libera o dinheiro e a Thread de Maria morre...

Pronto, agora o saldo da conta é de -R$ 100,00, pois sua aplicação permitiu um saque de R$ 1.100,00 em uma conta que só tinha saldo de R$ 1.000,00.

Agora modificando o código...

public class Conta{
   private Double saldo;

   public boolean sacar(double quantia){
      synchronized(saldo){
         if(saldo.doubleValue()>=quantia){
            saldo = Double.valueOf(saldo.doubleValue()-quantia);
            saldo.notifyAll();
            return true;
         }
         return false;
      }
   }

   public void depositar(double quantia){
      synchronized(saldo){
         saldo = Double.valueOf(saldo.doubleValue()+quantia);
         saldo.notifyAll();
      }
   }
}

Analisando a mesma situação com código sincronizado.

Maria vai ao caixa eletrônico para sacar R$ 600,00, ao digitar os dados o servidor inicia uma Thread para realizar o saque.

...

A Thread de Maria começa a executar primeiro, executa o if e verifica se o saldo é maior ou igual a quantia a ser sacada, como o saldo é de R$ 1.000,00 e a quantia é de R$ 600,00 entra no if para subtrair o valor do saldo, mas antes de subtrair o sistema operacional pára a Thread de Maria para executar a de João...

A Thread de João começa a executar, tenta acessar o objeto "saldo", mas como ele está travado por outra Thread, a Thread de João aguarda...

A Thread de Maria volta a executar de onde parou, subtrai os R$ 600,00 do saldo e retorna true, o caixa eletrônico então libera o dinheiro, Thread de Maria notifica todas as Threads que estava esperando aquele objeto e morre...

A Thread de João volta a executar, já que o objeto "saldo" não está mais bloqueado, executa o if, e como o saldo da conta é inferior à quantia a ser sacada, ela retorna false e o caixa eletrônico notifica o cliente de que o saldo é insuficiente, a Thread de João morre...

Esse é um caso simples do uso de sincronismo...

As questões sobre a posição do modificador, e de que tipo de objeto pode ser usado, já foi explicado nas outras respostas...

:wink:

Criado 2 de março de 2007
Ultima resposta 2 de mar. de 2007
Respostas 3
Participantes 4