Atomicidade de comandos

13 respostas
danbittencourt

Pessoal, será que alguém poderia me ajudar? Estou com o seguinte problema: preciso fazer com que dois ou mais comandos sejam executados de forma atômica. Esses comandos podem variar desde uma simples atribuição até a chamada de um método (dessa forma o método também deverá ser executado de forma atômica), sendo que o método pode ou não ser synchronized. Ex:

...
obj1.metodo(); // esse método é synchronized
obj2.outroMetodo();
isOk = true;
...

Eu quero fazer com que tudo isso seja executado de forma atômica. Tem como implementar isso em Java? Agradeço desde já qualquer idéia que alguém possa me dar!! :slight_smile:

13 Respostas

kaique

Tenta assim pra ver se funfa…

synchronized(this) {
   ...
   obj1.metodo(); // esse método é synchronized
   obj2.outroMetodo();
   isOk = true;
   ...
}

[]'s.

danbittencourt

oi kaique, vlw… vou tentar dessa forma e depois digo se funcionou!!

danieldestro

Atomicidade?

Você quer que “ou tudo seja executado, senão retorna ao estado original” ou você quer que o trecho de cógido seja executado serialmente, ou seja, sem paralelismo (threads simultâneas) ???

danbittencourt

eu quero que funcione de forma que se o primeiro comando executar, os outros comandos devem ser executados sem que o processo seja interrompido… que todos os comandos sejam executados como se fosse uma única instrução (ou seja, de forma atômica)… mais ou menos como uma transação em banco de dados: “ou tudo é executado, ou retorna ao estado original”…

danieldestro

Então synchronized não é a solução.
Creio que vai ter um belo de um trabalho pra implementar o que você deseja.

danbittencourt

eh dessa forma que eu descrevi anteriormente, entretanto nao sei se o “retorna ao estado anterior” serviria pra mim… o que eu queria mesmo eh que o processo nao fosse interrompido

danieldestro

Explique-se melhor.

danbittencourt

tipo assim: imagine que eu tenho várias threads com o mesmo código executando ao mesmo tempo… em um determinado momento uma das threads atinge o trecho de código com os seguintes comandos:

...
obj1.metodo();
obj2.outroMetodo();  
isOk = true;
...

o que eu quero é que, ao atingir o primeiro desses comandos, a thread execute os outros dois comandos sem que ela seja interrompida por nenhuma das outras threads entre a execução de um comando e outro!! entende?
será que tem como fazer?

danieldestro

Ai sim vc deve usar synchronized.
Isso não tem a ver com recuperação do estado original.

danbittencourt

tipo… acho que o uso do synchronized nao adianta no meu caso pq dessa forma a thread poderá ser interrompida por outra thread que não esteja no trecho com synchronized e eu nao desejo isso… queria que todo o trecho fosse executado sem nenhuma interrupção!! mas mesmo assim vou testar com o synchronized… pode ser q eu esteja errado!!
é pq eu nao sei se eu estou sendo claro no q desejo… auhauahauaha… é que o problema nao é de seção crítica… no problema com seção crítica a thread que executa sua seção crítica poderia ser interrompida por uma outra thread que nao estivesse executando sua seção crítica… no meu caso eu nao quero q a thread seja interrompida de forma nenhuma!! :smiley:

danieldestro

Isso não dá pra controlar, pois o sistema operacional que faz isso.
Mas acho que você pode simular isto com algum tipo de controle.
Mas, porque você ques isto?

danbittencourt

rapaz, é o seguinte; no meu sistema eu estou utilizando programação orientada a aspectos. existem várias threads executando o mesmo código… quando uma das threads atinge um determinado comando, esse comando é “capturado” pelo aspecto… aí o fluxo de execução passa para o asecto… esse aspecto executa o comando que a thread executaria e mais outro comando… por exemplo:

...
// esse comando faz parte do código da thread.
obj.metodo(id); // ao atingir esse comando o aspecto "captura" o fluxo de execução antes que o comando seja executado.
...
...
// esse código está no aspecto.
obj.metodo(id); 
System.out.println("A Thread " + id + " executou o método!");
...

o que eu quero é que o aspcto execute o comando que seria executado pela thread e mais outro comando (que no caso é o System.out), mas o aspecto nao pode ser interrompido por uma outra thread entre o primeiro comando e o System.out, senão o sistema perde a consistência

Dieval_Guizelini

danbittencourt ,

as threads concorrentes que você quer controlar são threads criadas pelo seu sistema, e muito provavelmente são objetos de uma classe sua.

Se isso for correto, você pode criar na sua classe uma propriedade static contendo uma lista de todas as threads (instancias) da classe criada, e antes de chegar nas instruções que você quer que seja executadas "isoladamente" você pode fazer algo assim:

synchronized (this) {
   for(Thread t : minhaListaThreads) {
      if( !this.currentThread().equals( t ) ) {   // ou algo q diferencie a thread atual
            t.wait();
      }
     
       // executa os seus métodos

      // e libera as threads novamente
     this.notifyAll();
  }

talvez ajude.

fw

Criado 17 de novembro de 2007
Ultima resposta 20 de nov. de 2007
Respostas 13
Participantes 4