Threads

12 respostas
G

Alguem sabe me falar como se deve programar os métodos de uma classe de forma a permitir que cada uma das threads que usam objetos desta classe tenham acesso exclusivo somente a partes específicas da representação destes objetos, enquanto outras partes dos mesmos objetos possam ser livre e concorrentemente acessadas por outras threads

12 Respostas

ViniGodoy

Use sincronização nos métodos que deseja acesso exclusivo, e não use nos que deseja acesso concorrente.

Claro que no caso dos de acesso concorrente, garanta que isso é possível.

Você sempre pode fazer acesso concorrente quando:

a) Seu objeto não altera qualquer tipo de estado;

b) Seu método  usa variáveis locais;

c) Você trabalha em objetos diferentes, para threads diferentes (usando threadlocal, por exemplo).

Se seu método usa atributos, garanta o acesso com sincronização.

G

Como processos concorrentes (threads) podem ser criados e sincronizados ?
Vc tem algum exemplo? ou poderia me explicar como fazer?

R

http://java.sun.com/docs/books/tutorial/essential/concurrency/

Rapapel

gardussi:
Como processos concorrentes (threads) podem ser criados e sincronizados ?
Vc tem algum exemplo? ou poderia me explicar como fazer?

Você não sincroniza Threads, você controla o acesso aos métodos com a palavra reservada “synchronized” na assinatura do método.
Adicionando “synchronized” você garante que somente uma Thread acessa aquele método por vez.

ViniGodoy

Rapapel:
Você não sincroniza Threads, você controla o acesso aos métodos com a palavra reservada “synchronized” na assinatura do método.
Adicionando “synchronized” você garante que somente uma Thread acessa aquele método por vez.

E isso não é sincronizar threads?

Além disso, synchronized não é a única forma de sincronizar duas threads. Você pode fazer duas threads serem sincronizadas por uma fila de mensagens, por exemplo.

É só o mecanismo. Você ainda tem as classes Barrier, Latch, BlockingQueue, que fazem diferentes tipos de sincronização. Para mais informações, dê uma olhada no pacote java.util.concurrent.

Rapapel

ViniGodoy:
Rapapel:
Você não sincroniza Threads, você controla o acesso aos métodos com a palavra reservada “synchronized” na assinatura do método.
Adicionando “synchronized” você garante que somente uma Thread acessa aquele método por vez.

E isso não é sincronizar threads?

Além disso, synchronized não é a única forma de sincronizar duas threads. Você pode fazer duas threads serem sincronizadas por uma fila de mensagens, por exemplo.

É só o mecanismo. Você ainda tem as classes Barrier, Latch, BlockingQueue, que fazem diferentes tipos de sincronização. Para mais informações, dê uma olhada no pacote java.util.concurrent.

Não. A JVM não te da garantias de qual thread irá executar, se eu sincronizo threads quer dizer que eu posso escolher uma linha de execução de threads, qual deve executar em determinado momento.

Essas que você citou mais Semaphore, as implementações de Deque, ConcurrentHashMap, FutureTask, etc… Não há garantias de qual thread irá executar em determinado momento, então não se sincroniza threads.

Não sendo tão ao pé da letra(chato rss), acaba sendo um jeito de “sincronizar threads”, mas isso não é o termo correto de se falar e não é o que realmente acontece, e pode acabar gerando dúvidas para algumas pessoas.

ViniGodoy

Bem, em momento nenhum, na literatura sobre threads do Java, usa-se a palavra “sincronismo” com o signficado de “garantir a ordem de execução”. Por isso gera estranheza sua resposta. E acho que assumir um significado que ninguém dá ao termo sim, gera confusão. Até porque, para todos os efeitos, deve-se assumir que duas threads rodam paralelamente, e esquecer que existe time-sharing. Bom, na verdade, a medida que o número de núcleos aumenta, isso torna-se cada vez mais verdade.

Se formos chatos com o português, o termo sincronismo é totalmente desapropriado. Sincronizar significa “criar simultaneidade em”, e os métodos sincronized fazem o oposto disso, eles serializam as threads que querem acessar um método, impedindo o sincronismo de duas linhas de execução. Só classes como Latch e Barrier criariam algum tipo de sincronismo, mas não os trechos de código marcados como “sincronized”. Só se for sincronismo do que está parado. :lol:

Rapapel

ViniGodoy:
Bem, em momento nenhum, na literatura sobre threads do Java, usa-se a palavra “sincronismo” com o signficado de “garantir a ordem de execução”. Por isso gera estranheza sua resposta. E acho que assumir um significado que ninguém dá ao termo sim, gera confusão. Até porque, para todos os efeitos, deve-se assumir que duas threads rodam paralelamente, e esquecer que existe time-sharing. Bom, na verdade, a medida que o número de núcleos aumenta, isso torna-se cada vez mais verdade.

Se formos chatos com o português, o termo sincronismo é totalmente desapropriado. Sincronizar significa “criar simultaneidade em”, e os métodos sincronized fazem o oposto disso, eles serializam as threads que querem acessar um método, impedindo o sincronismo de duas linhas de execução. Só classes como Latch e Barrier criariam algum tipo de sincronismo, mas não os trechos de código marcados como “sincronized”. Só se for sincronismo do que está parado. :lol:


Pelo que entendo de sincronia e que acho que é o entendimento popular é que sincronizar é fazer algo ao mesmo tempo, ou logo depois de uma outra coisa, ex: Nado sincronizado.
A questão não é ser chato com o português, o problema é que não sincronizamos threads, o momento ou ordem não esta sob nosso controle, então não fazemos nada com threads. O problema é que threads é um assunto meio chato e lembro que já tive algumas dificuldades com threads, então do jeito que você falou parece que nós sincronizamos de fato threads, para mim é claro que não temos controle das threads de quando e em que ordem as threads serão executadas, mas pode dificultar o entendimento de alguem.

Trechos de código sincronized cria sincronismo sim, dentro do que ele foi proposto que é não deixar mais de uma thread acessa-lo.

TiD

Vinigodoy, voce disse que o metodo deve ser sincronizado se mexer com atributos da classe (enfim, alterar o estado do objeto de alguma forma)… mas isso se um mesmo objeto em memoria for acessado por varias threads, correto ? Se cada thread tem seu objeto então não há necessidade do sincronismo.

Só estou levantando esse ponto pois vejo muito isso, o uso de sincronismo sem necessidade - as vezes fica dificil de distinguir quando um mesmo objeto vai ser acessado por varias threads. Apesar de não ser um overload drástico, se voce for enchendo o codigo de synchronized isso vai pesar no fim das contas.

G

eu ainda ñ enteidi como eu faço para sincronizar um Thread, alguem poderia me dar uma ajuda?

ViniGodoy

Exatamente. O java fornece uma maneira segura de se criar um objeto para cada thread, que é através do uso da classe ThreadLocal.

Realmente, para se usar threads efetivamente, é imprescindível:

  1. Ter um código organizado (ou seja, completamente diferente dos apresentados na prova de certificação);
  2. Ter papéis claros para as classes que usam as threads;
  3. Entender a função de cada thread.
  4. Entender os vários mecanismos de sincronização, o que pode gerar deadlock e quando threads estão ocupando a região crítica.

Geralmente, você irá garantir que uma thread acessa cada objeto de negócio através do planejamento.

ViniGodoy

Você faz assim:

public class SuaClasse
{
    private void metodoAcessadoPorTodos() {
         //Qualquer coisa aqui
    }

    private synchronized void metodoAcessadoPorUmDeCadaVez() {
         //Qualquer coisa aqui
    }

    private synchronized void metodoAcessadoPorUmDeCadaVez2() {
         //Qualquer coisa aqui
    }
}

No que se um thread estiver no metodoAcessadoPorUmDeCadaVez(), outro também não poderá entrar em metodoAcessadoPorUmDeCadaVez2(). Se você quer acesso concorrente nesses dois métodos, porém, com uma thread de cada vez em cada uma deles, terá que usar monitores diferentes:

public class SuaClasse
{
    private int[] monitor1 = new int[0];
    private int[] monitor2 = new int[0];    

    private void metodoAcessadoPorTodos() {
         //Qualquer coisa aqui
    }

    private void metodoAcessadoPorUmDeCadaVez() {
        synchronized (monitor1) {    
             //Qualquer coisa aqui
        }
    }

    private synchronized void metodoAcessadoPorUmDeCadaVez2() {
        synchronized (monitor2) {    
             //Qualquer coisa aqui
        }
    }
}

Cuidado que o uso de mais de um monitor torna possível a ocorrência de DeadLocks.

Criado 30 de julho de 2009
Ultima resposta 4 de ago. de 2009
Respostas 12
Participantes 5