olá. não intendo nada de threads. criei uma thread da mesma forma que vi no livro “java como programar”
mas não consigo pará-la.
fiz o seguinte:
criei a classe que implementa Runnable;
aí fiz ExecutorService exe = Executors.newFixedThreadPool(1);
instanciei a classe que implementa Runnable
e fiz exe.execute(v);
aí tudo bem,
mas quando coloco exe.shutdown(); a thread continua rodando. porque será?
Esse assunto já foi comentado aqui no fórum. Uma solução seria fazer alguma lógica para poder finalizar a execução do método run()…
[]'s.
É isso mesmo suarte, como o kaique disse vc precisa de uma condição de parada pro seu método run… ele é um metodo como outro qualquer e quando a execução dele acabar a thread vai acabar…
condição? nao sabia dessa. eu fiz o seguinte:
//classe interna
class Verificadora implements Runnable {
int tempo = 3000; //três segundos
public void run() {
while (true) {
try {
System.out.println("teste");
Thread.sleep(tempo);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//método que deveria parar a thread
public void verificarLog(boolean verificar) {
if (verificar) {
//exe já foi inicializada, ela é um ExecutorService
exe = Executors.newFixedThreadPool(1);
Verificadora v = new Verificadora();
exe.execute(v);
}else{
if (exe != null) exe.shutdown();
}
}
esse método deve ser chamado quando eu clicar em um botão, ou seja, quando clacar no botão uma vez, a thread inicia, quando clicasse novamente ela deveria parar. mas ela só inicia e não para. como resolvo isso?
bom eu não mostrei logo meu código porque se i que ele é horrível.
O problema está no seu:
while (true) {
Troca por alguma flag que vc desliga quando sua condição de saida ocorrer
while (verificarLog()) {
Algo desse tipo…
mas como faço isso? porque a única condição de saída é alguem apertar um botão.
e achei que quando alguem apertar o botão, se eu chamasse exe.shutdown(); ela pararia. pra que serve então esse shutdown(); ?
Olha pra acessar eventos do teclado vc deve usar um KeyListener… não lembro exatamente mas use um keyListener para setar uma flag dentro da sua classe e que a thread possa ler… o importante é vc de alguma maneira fazer com que um false seja retornado pelo laço while em algum momento da execução!
[quote=souarte]condição? nao sabia dessa. eu fiz o seguinte:
[/quote]
Vc pode criar uma condição, mas se essa condição não é real ,ou seja, se é um flag, então vc está fazendo gambiarra.
O que vc precisa é interromper a thread. Threads não são seres vivos, elas não morrem.
A diferença entre matar e interromper é que existe um método interrupt na Thread… :lol:
É por isso que existe a InterruptedException. Entende ?
Então a solução do teu problema é simples : Não faça gambiarra, use o catch como deve ser.
Eis como ficaria
//classe interna
class Verificadora implements Runnable {
int tempo = 3000; //três segundos
public void run() {
while (true) {
try {
System.out.println("teste");
Thread.sleep(tempo);
} catch (InterruptedException e) {
break; // sai fora do while
}
}
}
}
//método que deveria parar a thread
public void verificarLog(boolean verificar) {
if (verificar) {
//exe já foi inicializada, ela é um ExecutorService
exe = Executors.newFixedThreadPool(1);
Verificadora v = new Verificadora();
exe.execute(v);
}else{
if (exe != null) exe.interrupt(); // interrupt
}
}
[quote=sergiotaborda][quote=souarte]condição? nao sabia dessa. eu fiz o seguinte:
[/quote]
Vc pode criar uma condição, mas se essa condição não é real ,ou seja, se é um flag, então vc está fazendo gambiarra.
O que vc precisa é interromper a thread. Threads não são seres vivos, elas não morrem.
A diferença entre matar e interromper é que existe um método interrupt na Thread… :lol:
É por isso que existe a InterruptedException. Entende ?
Então a solução do teu problema é simples : Não faça gambiarra, use o catch como deve ser.
Eis como ficaria
//classe interna
class Verificadora implements Runnable {
int tempo = 3000; //três segundos
public void run() {
while (true) {
try {
System.out.println("teste");
Thread.sleep(tempo);
} catch (InterruptedException e) {
break; // sai fora do while
}
}
}
}
//método que deveria parar a thread
public void verificarLog(boolean verificar) {
if (verificar) {
//exe já foi inicializada, ela é um ExecutorService
exe = Executors.newFixedThreadPool(1);
Verificadora v = new Verificadora();
exe.execute(v);
}else{
if (exe != null) exe.interrupt(); // interrupt
}
}
[/quote]
Sua solução vai falar em caso do interrupt ocorrer quando a Thread não estiver dormindo.
[quote=victorwss]
Sua solução vai falar em caso do interrupt ocorrer quando a Thread não estiver dormindo.[/quote]
Não. Veja o javadoc
[quote=sergiotaborda][quote=victorwss]
Sua solução vai falar em caso do interrupt ocorrer quando a Thread não estiver dormindo.[/quote]
Não. Veja o javadoc
[quote]
public void interrupt()
Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
[u]If none of the previous conditions hold then this thread's interrupt status will be set.[/u]
Interrupting a thread that is not alive need not have any effect. [/quote]
E em Sleep:
[quote]sleep
public static void sleep(long millis)
throws InterruptedException
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
Parameters:
millis - the length of time to sleep in milliseconds.
Throws:
InterruptedException -[u] if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.[/u]
[/quote][/quote]
hmmm, quer dizer que se a thread for interrompida quando ela estiver no System.out.println e assim que ela entrar no sleep, o sleep lançará um InterruptedException? Pensei que ele só o fazia se fosse interrompida durante o sleep…
[quote=victorwss]
hmmm, quer dizer que se a thread for interrompida quando ela estiver no System.out.println e assim que ela entrar no sleep, o sleep lançará um InterruptedException? Pensei que ele só o fazia se fosse interrompida durante o sleep…[/quote]
“Interrompido” é um estado da thread. Ela lançará a exceção assim que possivel. O javadoc enumera as possibilidades.
Se nenhum acontecer o estado é mantido e ativado quando uma delas acontecer.
Interrupt foi adiconada à API exactamente para poder “matar” a thread. Os outros métodos não são garantidos - como quase tudo o que envolve Threads.
A tecnica da condição do while é válida tb, mas não se qualifica como 'matar" a thread.
[quote=sergiotaborda][quote=victorwss]Interrupt foi adiconada à API exactamente para poder “matar” a thread. Os outros métodos não são garantidos - como quase tudo o que envolve Threads.
A tecnica da condição do while é válida tb, mas não se qualifica como 'matar" a thread. [/quote][/quote]
E o interrupt se qualificaria como ‘matar’? pelo menos não está explicito no javadoc.
[quote=faelcavalcanti][quote=sergiotaborda][quote=victorwss]Interrupt foi adiconada à API exactamente para poder “matar” a thread. Os outros métodos não são garantidos - como quase tudo o que envolve Threads.
A tecnica da condição do while é válida tb, mas não se qualifica como 'matar" a thread. [/quote][/quote]
E o interrupt se qualificaria como ‘matar’? pelo menos não está explicito no javadoc. [/quote]
Na verdade esse método não mata a Thread. Apenas diz a ela que ela deve se suicidar. Mas quem tem que obedecer (ou não) é a própria Thread (e o programador).
Basicamente é o seguinte:
Thread1: Ah, eu odeio você Thread2, porque você não se mata?
Thread2: Ok, adeus mundo cruel.
Em java:
Thread1: thread2.interrupt();
Thread2: if (Thread.interrupted()) { … }
EDIT: Por sinal, você não precisa necessariamente matar a thread quando ela for interrompida. Você pode querer simplesmente parar alguma operação que ela esteja fazendo sem que ela morra.
O correto então é fazer a InterruptedException sair do while. E também testar se o interrupt não foi dado fora do sleep. O código fica assim:
//classe interna
class Verificadora implements Runnable {
int tempo = 3000; //três segundos
public void run() {
try {
while (!Thread.interrupted()) { //Verifica se o interrupt não foi chamado fora do Sleep.
System.out.println("teste");
Thread.sleep(tempo);
}
} catch (InterruptedException e) {
//Para o while caso haja um interrupt no sleep.
}
}
}
Thread.kill();
[quote=luistiagos]
Thread.kill();
[/quote]
Sim, funcionaria se não fosse um problema:
.
.
.
.
.
.
.
.
.
.
.
.
[size=18][color=red]ESSE MÉTODO NÃO EXISTE![/color][/size]
Você pode usar o método destroy(). Mas, olha só como o método destroy() é implementado:
@Deprecated
public void destroy() {
throw new NoSuchMethodError();
}
Você também pode usar o método stop(). Mas ele tem um @Deprecated bem grande por um bom motivo.
E o motivo é bom mesmo. O stop() deixa o sistema instável.
O ideal é programar sua thread para terminar graciosamente.
Ou deixar que a VM a mate no final da execução (para muitos tipos de serviço isso realmente não é um problema).
Ue e isto é m problema?
basta implementalo que ele passa a existir…
[quote=victorwss]EDIT: Por sinal, você não precisa necessariamente matar a thread quando ela for interrompida. Você pode querer simplesmente parar alguma operação que ela esteja fazendo sem que ela morra.[/quote]isto, porém achei o termo matar um pouco estranho apesar de ele continuar no stackpoint da pilha de execução de chamadas pelo runtime. mas blz!