Controlar a duração de um programa em tempo real usando JAVA

PHP, Java, JavaScript, XML, XHTML, HTML, CSS, ASP, Delphi, Assembly, LaTeX, C, UML, Flash, Perl, SQL, Python, Zope, Pascal, WML. Se conhece mais de 3 siglas referidas, este é o forum para si.

Moderadores: Administradores, Moderadores

Controlar a duração de um programa em tempo real usando JAVA

Mensagempor pescadorDigital » Sábado Mai 14, 2005 17:42

Alguém me pode dizer como tal se pode fazer ? É que estou fazendo um programa que deve suspender a execução de um loop no seu interior ao fim de x milissegundos, e não conheço nenhuma função em Java que permita fazer isso ? Tal é possível usando Threads ? Como nunca trabalhei com threads não faço a mínima ideia !!!

Desde já obrigado a quem responder
Imagem
Avatar do Utilizador
pescadorDigital
Aprendiz
Aprendiz
 
Mensagens: 69
Registado: Terça Dez 28, 2004 22:23

Mensagempor [PT]Devilishly » Sábado Mai 14, 2005 21:11

Boas!

Podes usar a class TimeUnitpara suspender a tua aplicação por determinado periodo de tempo:
Código: Seleccionar todos
            try {
                java.util.concurrent.TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException ignored) {
            }

Aplicando este codigo suspendes a execução do teu programa por dez segundos.

Fikem bem!
[PT]Devilishly
Novato
Novato
 
Mensagens: 11
Registado: Terça Abr 26, 2005 21:48

Mensagempor pescadorDigital » Sábado Mai 14, 2005 21:37

[PT]Devilishly Escreveu:Boas!

Podes usar a class TimeUnit
Fikem bem!


Obrigado pela sugestão . Mas o problema é que ainda tou a usar a Java 1.4.2 e esta classe é novidade na Java 1.5, de modo que não a posso usar. Outra coisa, em vez de "suspender" no topic, quero dizer "interromper definitivamente", enganei-me no termo :/ Quero é alguma coisa que permita interromper a execução do programa mesmo ao fim de um certo tempo. Não me pareça que fazer o seguinte
Código: Seleccionar todos
long antes = System.currenttimemilis();
do {
// faz qq coisa
depois = System.currenttimemilis()
} while (depois - antes ) < 10



seja a melhor solução, até porque tenho mais do que um simples loop no
código :|

mas a ideia de usar uma excepção que permita controlar o tempo está muito fixe, nunca tinha pensado nisso!
Imagem
Avatar do Utilizador
pescadorDigital
Aprendiz
Aprendiz
 
Mensagens: 69
Registado: Terça Dez 28, 2004 22:23

Mensagempor [PT]Devilishly » Sábado Mai 14, 2005 21:51

Boas!

Nao pensei muito sobre a tua dúvida e é provavel q haja uma solução mto melhor, mas uma possível solução:
Código: Seleccionar todos
        long inicio = System.currentTimeMillis();
        long actual = inicio;
        do {
            // faz qq coisa
            actual = System.currentTimeMillis();
        } while ((actual - inicio ) < 10*1000); // verifica se ja passaram dez segundos
        System.exit(0); // termina a palicacao


Fikem bem!
[PT]Devilishly
Novato
Novato
 
Mensagens: 11
Registado: Terça Abr 26, 2005 21:48

Mensagempor [PT]Devilishly » Domingo Mai 15, 2005 9:45

Boas!

Vou-te deixar um exemplo para se quiseres usar Threads para controlar as varias tarefas q tenham um determinado timeout para serem concluidas:
Código: Seleccionar todos
public class Tarefa implements Runnable{
   
    private String nomeTarefa;
    private int timeout; //o tempo maximo para exectuar esta instancia
   
    public Tarefa(String nomeTarefa,int timeout){
        this.nomeTarefa=nomeTarefa;
        this.timeout = timeout;
    }
   
    public void run() {
        long inicio = System.currentTimeMillis();
        long actual = inicio;
        do {
            // faz qq coisa
            System.out.println(nomeTarefa);
            actual = System.currentTimeMillis();
        } while ((actual - inicio ) < timeout); // verifica se ja passou o tempo
    }
   
    public static void main(String[] args) {
        Thread[] tarefas = new Thread[]{
            new Thread(new Tarefa("A",10*1000)),//vai ser executado durante 10 seg
            new Thread(new Tarefa("B",5*1000)),//vai ser executado durante 5 seg
            new Thread(new Tarefa("C",1*1000)),//vai ser executado durante 1 seg
            new Thread(new Tarefa("D",2*1000)),//vai ser executado durante 2 seg
            new Thread(new Tarefa("E",6*1000)),//vai ser executado durante 6 seg
            new Thread(new Tarefa("F",5*1000)),//vai ser executado durante 5 seg
        };
        for(int i=0; i<tarefas.length;i++)
            tarefas[i].start();
    }
}
Espero ter ajudado..:roll:

Fikem bem!
[PT]Devilishly
Novato
Novato
 
Mensagens: 11
Registado: Terça Abr 26, 2005 21:48

Mensagempor pescadorDigital » Domingo Mai 15, 2005 12:27

A tua ideia tá fixe e funciona muito bem. Obrigado.

Mas eu tinha uma ideia diferente, acho uma sobrecarga enorme estarem todas as tarefas ("threads") a verificarem o seu tempo de execução. Não seria suficiente deixar essa função de verificar o tempo de execução decorrido a uma única thread, e quando ocorresse o timeout, esta thread mandava uma mensagem às outras a dizer para terminarem a sua execução ? Tal é possível ? :)
Imagem
Avatar do Utilizador
pescadorDigital
Aprendiz
Aprendiz
 
Mensagens: 69
Registado: Terça Dez 28, 2004 22:23

Mensagempor [PT]Devilishly » Domingo Mai 15, 2005 16:21

Boas!

Nao sei bem em q contexto queres aplicar isso e por isso apenas estou a fazer suposições...
Diz ao certo o q queres fazer e em q contexto por forma a conseguirmos chegar ao uma solução melhor :)
Vou-te fornecer uma solução q usa um método q esta depreceated na API, mas q apenas é possível corrigi-lo se souber ao certo como é q funciona a aplicação.
O método em questao é o stop() e aki podes saber pk e como resolver esse problema para a tua aplicação específica.
Usei uma classe ThreadGroup, pois neste caso é o mais aconselhado :roll:
Código: Seleccionar todos
public class Tarefa implements Runnable{
    private String nomeTarefa;
   
    public Tarefa(String nomeTarefa){
        this.nomeTarefa=nomeTarefa;
    }
   
    public void run() {
       while(true)
            System.out.println(nomeTarefa);
    }
   
    public static void main(String[] args) {
       
        ThreadGroup grupo =  new ThreadGroup("Grupo de tarefas");
        new Thread(grupo,new Tarefa("A")).start();
        new Thread(grupo,new Tarefa("B")).start();
        new Thread(grupo,new Tarefa("C")).start();
        new Thread(grupo,new Tarefa("D")).start();
        new Thread(grupo,new Tarefa("E")).start();
        new Thread(grupo,new Tarefa("F")).start();
       
        long inicio = System.currentTimeMillis();
        long actual = inicio;
        int time = 10*1000;
        do{
            actual = System.currentTimeMillis();
        } while ((actual - inicio ) < time); // verifica se ja passou o tempo
        grupo.stop(); // metodo depreceated... :|
    }
}


Fikem bem!
[PT]Devilishly
Novato
Novato
 
Mensagens: 11
Registado: Terça Abr 26, 2005 21:48

Mensagempor pescadorDigital » Domingo Mai 15, 2005 17:11

Mais uma vez, obrigado pela resposta.
Eu estou a usar threads num trabalho prático em que preciso de implementar um jogo de Damas, toda esta parte já está feita, e, para adiantar mais alguns pormenores que não sei se serão necessário, estou a usar o algoritmo Minimax com cortes alfa-beta mas o programa que estou a usar tem como parâmetros: o tempo e tolerância, tempo é um tempo dentro do qual o programa deve dar uma resposta, tendo ainda mais um pouco de tolerância. Todos os tempos vêm em segundos.

O algoritmo minimax é recursivo e parte de um estado inicial, que pode ser representado por um estado actual do jogo de Damas, e cria uma árvore a partir do qual se pode ter uma ideia de todas as jogadas possíveis. Uma vez que o algoritmo é de profundidade primeiro, terá que ser escolhida uma profundidade máxima. Mas o aspecto mais importante é receber uma jogada ao fim do tempo pedido. Assim, a minha ideia era colocar uma thread para cada jogada inicial, assim por exemplo um movimento de uma peça para a esquerda e todos os seus descendentes são executados por uma thread, uma captura fica para outra thread. Quando cada thread executar o seu trabalho, actualiza uma variável que representa a pontuação máxima para aquela jogada, assim como o movimento ou captura associada à melhor jogada. Como são variáveis a ser usadas por entre todas as variáveis, logo se vê que em princípio terão de ficar dentro de um bloco synchronized para evitar acessos simultâneos. Finalmente, existiria uma tarefa completamente diferente de todas as outras cuja missão seria simplesmente contabilizar o tempo. Existe um método Thread.sleep, penso que se poderia utilizar . A tarefa em si não faria simplesmente nada, quando ela acordasse (terminasse o tempo de "sleep") terminava o programa devolvendo a melhor jogada utilizada até ao momento.
Imagem
Avatar do Utilizador
pescadorDigital
Aprendiz
Aprendiz
 
Mensagens: 69
Registado: Terça Dez 28, 2004 22:23

Mensagempor pescadorDigital » Domingo Mai 15, 2005 18:44

Bem, após algum tempo de pesquisa no tutorial do Java, acabei por encontrar aquilo que precisava: a classe Timer.

A classe Timer socorre-se de uma classe que deve derivar de TimerTask para executar o que se quer ao fim de um período de tempo especificado. No meu caso, fiz uma classe que implementa uma Thread que calcula os numeros de Fibonacci, e que é interrompida ao fim de 5 segundos, graças à acção do objecto TerminateTask, que ajusta a "flag" que mantém a execução da ThreadFibo enquanto a flag for falsa. Agora, mãos à obra para aquilo que interessa ;)

Código: Seleccionar todos
import java.util.*;

class ThreadFibo implements Runnable
{
   long somaFibo;
   long termo_2;
   long termo_1;
   boolean end;
   Timer timer;
   long antes;
   long depois;
   
   public ThreadFibo()
   {
      somaFibo = 0;
      termo_2 = 1;
      termo_1 = 1;
      end = false;
      timer = new Timer();
      timer.schedule(new TerminateTask(),5000);
      antes = System.currentTimeMillis();
   }
   
   class TerminateTask extends TimerTask
   {
      public void run()
      {
         end = true;
         timer.cancel();
      }
   }
   
   public void run()
   {
      do {
         somaFibo = termo_2 + termo_1;
         termo_2 = termo_1;
         termo_1 = somaFibo;
         System.out.println (somaFibo);         
      } while (!end);
      depois = System.currentTimeMillis();
      System.out.println("TEMPO -> " + (depois-antes) );
   }
   
}

public class Threadtry1
{
      
   public static void main(String[] args) throws Exception
    {
       ThreadFibo t1 = new ThreadFibo();
       Thread t = new Thread(t1);
       t.start();
            
    }
}
Imagem
Avatar do Utilizador
pescadorDigital
Aprendiz
Aprendiz
 
Mensagens: 69
Registado: Terça Dez 28, 2004 22:23

Mensagempor [PT]Devilishly » Domingo Mai 15, 2005 22:06

Boas!

Sim, o timertask é particularmente importante para correr determinadas tarefas a um tempo específico.
De qq maneira, para o teu caso, e como queres executar apenas um calculo sempre q seja necessário(e nao uma tarefa predefinida), acho q nao seja o mais coerente.:roll:

Por exemplo, na classe Threadtry1 q indicaste, um Timer é desnecessario pois poderias resolver esperando q o tempo terminasse e simplesmente colocando a flag end a false.
Exemplo:
Código: Seleccionar todos
import java.util.*;

class ThreadFibo implements Runnable {
    long somaFibo;
    long termo_2;
    long termo_1;
    boolean end;
    // Timer timer;
    long antes;
    long depois;
   
    public ThreadFibo() {
        somaFibo = 0;
        termo_2 = 1;
        termo_1 = 1;
        end = false;
        //timer = new Timer();
        //timer.schedule(new TerminateTask(),5000);
       
        antes = System.currentTimeMillis();
    }
   
/*  class TerminateTask extends TimerTask
   {
      public void run()
      {
         end = true;
         timer.cancel();
      }
   }*/
   
    public void run() {
        do {
            somaFibo = termo_2 + termo_1;
            termo_2 = termo_1;
            termo_1 = somaFibo;
            System.out.println(somaFibo);
        } while (!end);
        depois = System.currentTimeMillis();
        System.out.println("TEMPO -> " + (depois-antes) );
    }
   
}

public class Threadtry1 {
   
    public static void main(String[] args) throws Exception {
        ThreadFibo t1 = new ThreadFibo();
        Thread t = new Thread(t1);
        t.start();
        // Apenas esperas q passe 5 segundos e depois colocas a flag end=false;
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {}
        t1.end = true;
    }
}
Atenção q tb deves ter atenção de nao deixar variaveis de class como 'friendly', com o risco de tornares a tua aplicação com o mmo potencial de erros como se estivesses a programar em C\C++ :(

De qq maneira se assim resolve o teu problema bem melhor :)

Se tiveres mais alguma dificuldade contacta Imagem

Fikem bem!
[PT]Devilishly
Novato
Novato
 
Mensagens: 11
Registado: Terça Abr 26, 2005 21:48


Voltar para Programação

Quem está ligado:

Utilizadores a ver este Fórum: Nenhum utilizador registado e 4 visitantes

cron