• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

magician

Java Threads

21 mensagens neste tópico

Após ler algumas coisa sobre o assunto e já perceber o funcionamento e implementação das mesmas ainda me falta aqui uma coisa para conseguir por o meu programa a funcionar.

Acho que a forma mais simples é explicar o que quero fazer +-.

Tenho 3 Classes que representão 3 funcionalidades diferentes P1,P2 e P3 estas classes já se encontram extend a Thread e com os métodos run() e interrupt() implementados agora só precisava de garantir que o P2 só é iniciado depois de P1 ter terminado e por sua vez P3 depois de P2 terminar. Mas não estou a conseguir fazer fazer com que esta ordem seja respeitada os 3 Processos arrancam ao mesmo tempo sem esperarem uns pelos outros :S

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E cada thread não pode iniciar a outra ao terminar?

Uma forma, a mais simples que me ocorre agora, seria iniciares as 3 threads e suspenderes imediatamente a execução da P2 e P3. Quando a P1 acaba, "acorda" as outras duas. Seguindamente a P3 vê que não é a vez dela executar e "adormece". Quando a P2 termina avisa a thread que falta.

Desculpa mas não sabendo mais do que estás a fazer posso estar a dar indicações erradas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Relativamente a fazer uma thread abrir outra não me parece possivel visto que as threads que tou a usar são as 3 iguais e unica diferença é o processo que cada uma arranca com o método exec().

Quanto a meter as threads a dormir também pensei nisso mas o método sleep tem de receber um tempo como argumento e eu não sei quanto tempo vai levar a thread anterior a executar. :S

Desculpa mas não sabendo mais do que estás a fazer posso estar a dar indicações erradas.

O quero fazer ao certo é tenho uma class Processo e vai receber uma String como argumento e depois vai fazer exec() dessa String e quero fazer 3 objectos Processo cada 1 deles com um comando diferente mas dependentes de cada um como disso o P2 fica dependente de P1 e P3 de P2.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes usar uma condição e "pooling" activo.

No caso, parece-me natural que as threads conheçam a thread que depende delas, dessa forma podes ter as threads em "pooling" activo e quando uma acaba consegue desbloquear a outra.

private boolean dormir = true;

(...)
//aqui ficará o código de início da thread....

//thread a dormir
while(dormir) {
    sleep(1000);
}

/*thread acordou e vai continuar a sua execução, no fim, antes de terminar
invoca o método acordar da thread que depende dela.
*/
(...)

/*
não será necessário sincronizar o método, mas como não sei bem como corre a execução do programa....
*/
public synchronized acordar() {
    dormir = false;
}

(...)

Neste caso as threads passam a receber a thread que depende delas. Não sei até que ponto te ajuda....

Não será possível teres um objecto à parte que controle qual a thread que tem de executar?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

ah esqueci-me de dizer que podes acordar a thread usando o método interrupt e que podes usar a excepção InterruptedException para controlar o comportamento quando a thread é interrompida....

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

hum... também podes usar os "Join".

Se as threads souberem por quem devem esperar, em oposto ao que disse acima, em que sabiam quem esperava por elas, podem simplesmente esperar que essa thread acabe antes de continuarem a sua execução.

private Thread esperar;
(...)
//código para iniciar a thread...
(...)

//a thread vai agora ficar à espera que a outra termine.
esperar.join();
//restante código necessário a esta thread

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu por acaso pensei em colocar a class toda sincronizada para não haver erros de sincronismo.

Relativamente ao join não percebi muito bem :S Como é que a thread sabe por qual thread esperar ?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A ideia era acrescentares no construtor uma referência para a tread pela qual têm de esperar. Tinhas de passa tu, e dizer qual era a thread :)

Depois esperavas por essa thread.

Quanto a sincronizares, não precisas de sincronizar a classe, apenas os métodos de acesso a recursos criticos, mas se tens 3 threads diferentes e elas não partilham o mesmo recurso não tens problemas de concorrência.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isto do sleep não ta a funcionar lá muito bem.

Só se percebi mal a ideia.

Ora eu fiz assim...

Na class processo tenho um construtor que recebe uma String comando, inicializa a variável comando e a variável dormir como true.

Depois tenho o método run() que tem um while que verifica se está a dormir como mostras-te la acima depois desse while ele faz o exec(comando) e tenho o método acordar como mostras-te.

Depois na class principal tenho

Processo p1 = new Processo("comando1");
Processo p2 = new Processo("comando2");
Processo p3 = new Processo("comando3");
p1.run();
p2.run();
p3.run();

if(!p1.isAlive()){
p2.acordar();
if(!p2.isAlive()){
   p3.acordar();
  }
}

Mas por algum motivo isto não ta a funcionar muito bem porque o p2 nunca passa do estado de dormir mesmo depois de o acordar. :S

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Confusão!!!

while (Count==N) {
   try {
      wait();
   } catch (InterruptedException e) {}
}

N é o numero do thread. Criado no construtor do thread.

Count = Count+1;
notifyAll();

Encaixa o código no lugar correcto e já tá.

E claro, o Count tem de ser partilhado.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Confusão!!!

while (Count==N) {
   try {
      wait();
   } catch (InterruptedException e) {}
}

N é o numero do thread. Criado no construtor do thread.

Count = Count+1;
notifyAll();

Encaixa o código no lugar correcto e já tá.

Juro que não percebi :S

Quer dizer percebi o funcionamento mas nao tou a ver como posso meter isso no meu programa :S

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

No código que fizeste o if pode ser testado antes sequer da thread p1 ser iniciada, nada te garante isso... deixa cá ver se escrevo qualquer coisa....

(...)
Processo p1 = new Processo("comando1", null);
Processo p2 = new Processo("comando2", p1);
Processo p3 = new Processo("comando3", p2);

p1.run();
p2.run();
p3.run();
(...)

Classe Processo

(...)
private Thread threadControlo = null;
private String comando = ""; 

//Construtor
public Processo(String comando, Thread threadControlo) {
   this.comando = comando;
   this.threadControlo = threadControlo;
}

//run
public void run() {
   //esperar
   if(threadControlo != null)
       threadControlo.join();

   //execução normal
   (...)
}

Não sei se me fiz entender. Optei pela segunda via, usar o método join. Para usar o sleep seria algo como:

(...)
Processo p1 = new Processo("comando1", p2);
Processo p2 = new Processo("comando2", p3);
Processo p3 = new Processo("comando3", null);

p1.run();
p2.run();
p3.run();
(...)

Classe Processo

(...)
private Thread threadControlo = null;
private String comando = "";
private boolean dormir = true; 

//Construtor
public Processo(String comando, Thread threadControlo) {
   this.comando = comando;
   this.threadControlo = threadControlo;
}

//run
public void run() {
   //esperar
   while(dormir) {
      sleep(1000);//pode ser reduzido mas 1s deve ser suficiente. Depende do objectivo
   }

   //execução normal
   (...)

   //antes de terminar
   threadControlo.acordar();
}

public void acordar() {
  dormir = false;
}

Eu gosto mais da solução que escrevi em primeiro lugar, usando o método "join". Mas, novamente, posso estar aqui a dizer asneiras e isto não servir para o que queres :(

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Confusão!!!

while (Count==N) {
   try {
      wait();
   } catch (InterruptedException e) {}
}

N é o numero do thread. Criado no construtor do thread.

Count = Count+1;
notifyAll();

Encaixa o código no lugar correcto e já tá.

Juro que não percebi :S

Quer dizer percebi o funcionamento mas nao tou a ver como posso meter isso no meu programa :S

Basicamente, pela mesma ordem que tá. Na função run.

Mas tens de modificar os construtores par inserir o numero do processo. E tens de por os processos a partilhar a variavel Count.

Quando o processo n1 acaba a execução acorda os outros,  mas só o processo que tem o numero seguinte vai seguir com a execução.

Ó enganei-me, é != e não igual no while.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
E tens de por os processos a partilhar a variavel Count.

Tens a certeza que estás a falar de Java? Agora eu também fiquei confuso....

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
E tens de por os processos a partilhar a variavel Count.

Tens a certeza que estás a falar de Java? Agora eu também fiquei confuso....

Qual é o problema? Count é uma variavel, pronto count.

Mas tens de usar alguma tecnica para passar o parametro by ref. Porque java só passa by value.

Pode criar uma classe Wrapper, ou um array de um elemento.

Ver isto http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4029223

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não precisas da variável a não ser que as threads sejam controladas por entidades externas.

Só fiquei confuso porque, count é tipico de C++, tal como "número do processo" :(

Peace.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pois, mas foi só um nome.

Sem a variavel não consegues saber qual a thread que se segue na execução. Não estou a ver como fazer mais simples.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pois agora já percebi o que me tava a atrofiar era aqueles == e tal como eu pensei era um != :(

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se passares a thread, como mostrei, consegues e não tens pooling activo, o que é uma vantagem. Mas não sei se se adpata ao código que o magician quer...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já consigo :( Jś esperam umas pelas outras ;) usei o método do join.

Mas ainda tenho um problema que pensei que resolvia também mas afinal não é o seguinte....

Tenho o interface gráfico feito e ao carregar num botão ele chama as 3 threads referidas o problema é que o programa fica congelado até terminar as 3 threads :S supostamente isto não devia de acontecer ou estarei enganado ??

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Realmente isso não deveria acontecer, parece que o teu programa também está à espera que, pelo menos uma thread termine. Podes mostrar o código?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora