| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2011 07:31:59
|
lina
Moderador
![[Avatar]](/images/avatar/8849f0a976aa5332853e848655a1d28f.jpg)
Membro desde: 23/12/2006 21:05:04
Mensagens: 3083
Offline
|
Oi,
Precisei agendar uma tarefa para ser executada de 30 em 30 segundos. Para isso, utilizei um ScheduledExecutorService :
Se por acaso neste tempo de 30 segundos a minha tarefa não chegou a terminar (pois existem rotinas complexas e bababa), o scheduleAtFixedRate fará com que inicie uma outra tarefa.
Para que isso não ocorra foi feito:
Porém, se o meu processamento da tarefa ficar bloqueado, a função finally nunca será executada e a timer não rodará mais a tarefa.
Seria uma solução passar a utilizar uma simples Thread?
Tchauzin!
This message was edited 3 times. Last update was at 27/07/2011 07:33:58
|
Você é novo no GUJ? Vai criar um tópico e colar seu código-fonte? Leia aqui antes, por favor!
http://www.guj.com.br/posts/list/50115.java
Se o seu tópico foi respondido e você está satisfeito, segue:
- Pressione o botão <Edit> de seu primeiro post
- Acrescente no final do título a tag [RESOLVIDO]
@gujgirl
http://www.restartfans.hdfree.com.br
Meu blog:
http://www.runthecode.wordpress.com
Tchauzin! |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2011 08:14:21
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
Porém, se o meu processamento da tarefa ficar bloqueado, a função finally nunca será executada e a timer não rodará mais a tarefa.
Usar uma simples thread não resolve seu problema também. Será que melhorando a especificação você consegue enxergar melhor o problema? Um exemplo de especificação seria:
- agendar uma tarefa de 30 em 30 segundos;
- se a tarefa anterior estiver em execução, não deve ser executada outra em paralelo;
- o tempo que essa tarefa deve durar não deve exceder 150 segundos - consideraremos que ela ficou "travada" se passar desse tempo;
- Se passar de 150 segundos, cancelar essa tarefa.
Note que "cancelar uma tarefa" não se faz com Thread.stop e sim com algum método cancel da interface Future. Exemplo: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/FutureTask.html#cancel%28boolean%29
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2011 08:21:04
|
lina
Moderador
![[Avatar]](/images/avatar/8849f0a976aa5332853e848655a1d28f.jpg)
Membro desde: 23/12/2006 21:05:04
Mensagens: 3083
Offline
|
entanglement wrote:
Porém, se o meu processamento da tarefa ficar bloqueado, a função finally nunca será executada e a timer não rodará mais a tarefa.
- se a tarefa anterior estiver em execução, não deve ser executada outra em paralelo;
Oi,
Sim... a grande dificuldade está em saber quando uma tarefa esta em execução. Por isso tentei a variável booleana.
Tchauzin!
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2011 08:25:42
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
A variável booleana não precisa ser usada se você usar FutureTasks. Eu vou ver se dou um exemplo do que eu falei.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2011 08:44:17
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
A minha especificação está incompleta - o que ocorre, por exemplo, se uma tarefa levou 45 segundos em vez de 30? A próxima é iniciada 15 segundos depois (porque você executa uma tarefa de 30 em 30 segundos, mas se ela levou mais tempo que isso você simplesmente "pula" essa vez) ou então você executa a próxima tarefa imediatamente?
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2011 08:47:04
|
lina
Moderador
![[Avatar]](/images/avatar/8849f0a976aa5332853e848655a1d28f.jpg)
Membro desde: 23/12/2006 21:05:04
Mensagens: 3083
Offline
|
entanglement wrote:A minha especificação está incompleta - o que ocorre, por exemplo, se uma tarefa levou 45 segundos em vez de 30? A próxima é iniciada 15 segundos depois (porque você executa uma tarefa de 30 em 30 segundos, mas se ela levou mais tempo que isso você simplesmente "pula" essa vez) ou então você executa a próxima tarefa imediatamente?
Oi,
Aguardo 15 segundos.
Tchauzin!
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2011 10:18:53
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
Pois bem, olhando a especificação de scheduleAtFixedRate, ele diz que a tarefa pode começar atrasada mas não será pulada. Ou seja, não dá para usar diretamente scheduleAtFixedRate; provavelmente você terá de usar um timer simples, para disparar as tasks, e usar o método cancel para parar algo que demorou demais. O problema chato é que um Future<?> ou um FutureTask<?> é um pouco desacoplado de um Runnable ou Callable, mas você, dentro do seu Runnable ou Callable, provavelmente terá de ter acesso à variável do tipo Future ou FutureTask para checar se sua tarefa foi cancelada, por exemplo.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2011 12:04:26
|
lina
Moderador
![[Avatar]](/images/avatar/8849f0a976aa5332853e848655a1d28f.jpg)
Membro desde: 23/12/2006 21:05:04
Mensagens: 3083
Offline
|
entanglement wrote:Pois bem, olhando a especificação de scheduleAtFixedRate, ele diz que a tarefa pode começar atrasada mas não será pulada. Ou seja, não dá para usar diretamente scheduleAtFixedRate; provavelmente você terá de usar um timer simples, para disparar as tasks, e usar o método cancel para parar algo que demorou demais. O problema chato é que um Future<?> ou um FutureTask<?> é um pouco desacoplado de um Runnable ou Callable, mas você, dentro do seu Runnable ou Callable, provavelmente terá de ter acesso à variável do tipo Future ou FutureTask para checar se sua tarefa foi cancelada, por exemplo.
Oi,
Por fim, acho que vou acabar achando uma outra solução. Agora a tarde começarei a ver essa codificação! Minha manhã foi totalmente ocupada por cursores abertos excedidos na base de dados. rs Obrigada!
Tchauzin!
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 27/07/2011 16:47:06
|
ViniciusLM
Debugger
![[Avatar]](/images/avatar/e74a9d09ab697a9d0caf49632532328e.jpg)
Membro desde: 18/11/2009 09:02:26
Mensagens: 58
Offline
|
Boa tarde pessoal, desculpa se não entendi direto maaaas...
Mas será mesmo que uma thread não resolveria o problema?
chamando uma classe voce pode fazer um loop infinito com o while(true) e no finally voce coloca o tempo que ela deve aguardar até comecar denovo, entao quando ela terminar de fazer a funcao ela passa pelo finally e espera 30 segundo, depois por causa do while ela executa a funcao denovo.
public class clsExecuta extends Thread {
public void run() {
while (true) {
try {
//executa funcao;
} catch (Exception ex) {
System.out.println(ex);
} finally {
try {
this.sleep(30000);
} catch (InterruptedException ex) {
System.out.println(ex);
}
}
}
}
}
Ajuda aeee: http://vwdarkside.com/en/jedi/vinicius-michelan-251769
This message was edited 1 time. Last update was at 27/07/2011 16:48:26
|
Me ajude a me tornar um Jedi melhor.
Acesse http://vwdarkside.com/en/jedi/vinicius-michelan-251769 para aumentar meu nível. |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2011 08:01:01
|
lina
Moderador
![[Avatar]](/images/avatar/8849f0a976aa5332853e848655a1d28f.jpg)
Membro desde: 23/12/2006 21:05:04
Mensagens: 3083
Offline
|
Oi,
Sim. Dessa forma resolveria. O grande problema é que o tempo de 30seg a 30seg não seria confiável.
Tchauzin!
|
Você é novo no GUJ? Vai criar um tópico e colar seu código-fonte? Leia aqui antes, por favor!
http://www.guj.com.br/posts/list/50115.java
Se o seu tópico foi respondido e você está satisfeito, segue:
- Pressione o botão <Edit> de seu primeiro post
- Acrescente no final do título a tag [RESOLVIDO]
@gujgirl
http://www.restartfans.hdfree.com.br
Meu blog:
http://www.runthecode.wordpress.com
Tchauzin! |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2011 09:19:05
|
ViniciusLM
Debugger
![[Avatar]](/images/avatar/e74a9d09ab697a9d0caf49632532328e.jpg)
Membro desde: 18/11/2009 09:02:26
Mensagens: 58
Offline
|
hummm e se vc tentar isso:
cria essa classe que te retorna as horas em milisegundos
public int getDataMili() {
Date data = new Date();
int hora = data.getHours() * 60 * 60 * 1000;
int minuto = data.getMinutes() * 60 * 1000;
int segundo = data.getSeconds() * 1000;
int time = hora + minuto + segundo;
return time;
}
public class clsExecuta extends Thread {
public void run() {
int ultimotime = getDataMili();
while (true) {
try {
//executa funcao;
} catch (Exception ex) {
System.out.println(ex);
} finally {
try {
int atualtime = getDataMili();
int segundos = atualtime - ultimotime;
if (segundos < 0) {
segundos = segundos + 86400000;
}
segundos = (segundos - 30000) * -1;
System.out.println("Esperar: " + segundos);
while (segundos < 0) {
System.out.println("Processo demourou mais que 30 segundos: " + segundos);
segundos = (segundos + 30000);
System.out.println("Então esperar:" + segundos);
}
ultimotime = atualtime;
this.sleep(segundos);
} catch (InterruptedException ex) {
System.out.println(ex);
}
}
}
}
}
Desse jeito ele verifica quanto se passou desde o comeco da ultima execucao, se o tempo for menor que 30000 ele vai esperar a diferenca, por exemplo ele demorou 25 segundos entao segundos = (25000 - 30000) * -1; segundos = 5000.
se ele demorou 45 segundos segundos = (45000 - 30000) * -1; segundos = -15000 dai como é menor que zero entra no while segundos = -15000 + 3000; segundos = 15000 e assim por diante.
Nao estou com muito tempo para fazer mais testes mas sera que ajuda ou não é isso que vc precisa ?
This message was edited 1 time. Last update was at 28/07/2011 09:20:29
|
Me ajude a me tornar um Jedi melhor.
Acesse http://vwdarkside.com/en/jedi/vinicius-michelan-251769 para aumentar meu nível. |
|
|
 |
|
|