Olá a todos,
Desta vez o problema é um pouco mais complexo…
Tenho um metodo que recebe como parametro um valor boleano, este indica se outro metodo será executado paralelo ou não.
[code]
int i=0;
public void atualiza(boolean valor){
// Este parametro vai determinar se
if(valor){
new Thread(new Runnable(){
//chama o metodo a ser executado em segundo plano
faz();
}).start();
}else{
faz();
}
}
public void faz(){
// Realiza a operação
i++;
}[/code]
Já consegui colocar pra outra Thread atualizar o JProgresBar, o problema é o seguinte:
O usuario pode excolher entre executar normalmente o metodo - faz();
Ou optar por coloca-lo em outra Thread pra que seu processamento seja realizado em background.
o porque disso?? Imaginemos que o metodo faz(), atualiza o valor de um inteiro, caso queira utilizado pra calculo ou afins, o metodo a execução da primeira Thread so pode ser continuada quando a outra for terminada, para que o valor do inteiro seja o valor de toda a execução - Pensando em uma situação mais real, carregar o Hibernate ou realizar uma consulta muito demorada…onde os valores importam nesta outra Thread, imaginemos que seja uma tela swing !
O problema é que se colocar na mesma thread o Jprogressbar fica parado por conta do processamento da consulta, se colocar em outra Thread pra que realize em segundo plano, nao tem como pegar os valores reais da consulta…
Como proseguir???
Cara, não sei se entendi, mas um SwingWork não te resolve?
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/worker.html
Se tu precisar de resultados intermediários para popular a tua tela, pode ver isso
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/interim.html
O processamento terá que rodar em paralelo, em outra thread. Disso você não tem como escapar.
Agora, você pode fazer com que a thread que depende do processamento completo, espere a thread que está processando. Há várias formas de fazer isso:
- Use o método join() na thread que espera:
[code]public void atualiza(boolean esperar){
// Este parametro vai determinar se
Thread t = new Thread(new Runnable() {
@Override
public void run() {
faz();
}
});
t.start()
//Espera t terminar
if (esperar) {
t.join();
}
}[/code]
- Usar as interfaces Future e Callable:
http://www.guj.com.br/posts/list/50321.java#264620
http://java-x.blogspot.com/2006/11/java-5-concurrency-callable-and-future.html
Uffa… Demorei porque tava estudando as interfaces que o Vini passou…
Algumas duvidas surgiram. Mas vamos ao que interessa, vou explicar melhor meu problema:
Tenho uma Thread A que é um JDialog e contem um JProgressBar
class abstract Tela extends JDialog{
private JProgressBar progress;
private JLabel text;
//Este metodo é chamada no momento que será exibido a classe Tela
public abstract void executa();
}
Agora tenho outra Thread B, que é uma responsavel apenas pelo processamento do um metodo executa da classe Tela…
A Thread B consegui coloca-la pra rodar em background com SeingWork, no metodo doInBackground(), ai ela fica executando o metodo.
Agora o usuario tem duas opções ou mostra esta tela enquanto o metodo é processado e continua com a Thread original, ou “trava” a thread original até o momento que o metodo seja executado.
Novamente, porque isso?
[code]class Tela 2 extends Tela{
public void executa(){
// Se aqui for o carregamento de um arquivo, uma consulta que preenche um list…Em fim algum processamento que a execução deste metodo influa no processamento geral, neste caso teriamos que "trava " a outra Thread até que este metodo seja completamente executado…
}
}[/code]
Uma das coisas que pensei foi cirar um “gerenciador” pra manter as duas Threads sincronizadas, pois mesmo tento que esperar o processamento do metodo quero que o progress fique fucnioando… Na outra optica quando o resultado do metodo nao importa e pode continar o processamento da Thread original, já funciona direitinho…
E agora???
Tentei fazer desta forma e tambem nao funcionou da maneira que desejo…
int i = 0;
public void altera(boolean altera) {
// Tela que contem apenas um JDialog
final DaxWindow p = new DaxWindow();
Thread t = new Thread(new Runnable() {
public void run() {
try {
// Método de processamento demorado
for (int j = 0; j < 15000; j++) {
System.out.println("J : " + j);
i++;
}
p.setVisibleWindows(false);
} catch (Exception e) {
}
}
});
t.start();
// Exibe um JDialog com o progressBar
p.execute("Jobiando....");
System.out.println(" Depois do metodo : " + i);
}
Quando chamo este metodo ele exibe normal a outra Janela com o progressbar até o momento que o metodo é finalizado…
Tenho duas possibilidade:
- Executar até que o metodo seja finalizado
- Executar até que o metodo seja finalizado e somente apartir dai continuar o processamento…
Para a segunda questão, queria atualizar o valor de i teria que ser 15000, mas quando eu utilizo
Ele trava a outra tela, porque, não sei…
Tentei tomar como guiia este exemplo:
http://www.guj.com.br/posts/list/20464.java#108235
Mas… a duvida continua…