Threads Daemon - Não funcionando

7 respostas
C

Pessoal boa noite.
Antes de mais nada, digo que já procurei no google dezenas de vezes, sempre obtive as mesmas respostas, e nunca funciona!
Estou tentando setar uma Thread como daemon, para que ela continue rodando após o final da execução do meu main.
Segue o código:

package javaapplication1;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JavaApplication1 {

    public static void main(String[] args) {
        
        Thread someThread = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
              try {
        
                    File f = new File("test.txt");
                    FileWriter fw = new FileWriter(f);
        
                    for(int i = 0;i<1000;i++){

                            fw.append('\n');
                            fw.append('a');
                            System.out.println(i);
                    }

                    fw.close();

                  } catch (IOException iOException) {
                  }
            }
        });
        
        someThread.setDaemon(true);
        System.out.println(someThread.isDaemon());
        someThread.start();
        
    }
}

A idéia é simples, abrir um file, fazer o append de letras ‘a’, e encerrar.
O problema que, mesmo estando como daemon, as vezes cria um arquivo vazio, e as vezes nem cria nada, e nunca chega a escrever.
Se eu setar como false no setDaemon, funciona.
(Aquele println do IsDaemon, sempre imprime true)
Alguém me dá uma luz, pq o meu daemon está “morrendo” quando o main finaliza? Pelo que li, essa thread, setada como daemon deveria continuar rodando em background, até que terminasse.

7 Respostas

ViniGodoy

É justamente ao contrário. Threads deamon são feitas para não segurar a execução do programa.

Veja o que diz a documentação:
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDaemon(boolean)

The Java Virtual Machine exits when the only threads running are all daemon threads.

Quando a JVM finaliza, todas as threads daemon finalizam junto.
Isso não é só uma característica da VM, mas do SO como um todo.

Uma vez que seu programa finaliza, não dá para deixar threads para trás rodando.

S

ViniGodoy:
É justamente ao contrário. Threads deamon são feitas para não segurar a execução do programa.

Veja o que diz a documentação:
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDaemon(boolean)

The Java Virtual Machine exits when the only threads running are all daemon threads.

Quando a JVM finaliza, todas as threads daemon finalizam junto.
Isso não é só uma característica da VM, mas do SO como um todo.

Uma vez que seu programa finaliza, não dá para deixar threads para trás rodando.

Na verdade a JVM finaliza (automaticamente) se todas as Threads ativas forem daemon, ou seja, se não tiver mais nenhuma Thread não-daemon rodando.
Quando a JVM finalizar (automaticamente ou, por exemplo, depois de um System.exit) TODAS as Threads finalizam, independente de ser daemon ou não!

C

ViniGodoy:
É justamente ao contrário. Threads deamon são feitas para não segurar a execução do programa.

Veja o que diz a documentação:
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDaemon(boolean)

The Java Virtual Machine exits when the only threads running are all daemon threads.

Quando a JVM finaliza, todas as threads daemon finalizam junto.
Isso não é só uma característica da VM, mas do SO como um todo.

Uma vez que seu programa finaliza, não dá para deixar threads para trás rodando.

ViniGodoy, imagino que daemons sejam processos que rodam em background. Dessa forma, não faz muito sentido, após o fim de meu main, os daemons morrerem junto.
Eu interpreto isso: “The Java Virtual Machine exits when the only threads running are all daemon threads.” como sendo, “Todas as não daemon morreram, então o programa principal encerra.” e não necessariamente ele mata os daemons.

E como o Samuel S disse, o programa termina quando todas as não daemon acabam, dessa forma imagino que as que são daemon, continuam rodando até o fim da execução.
De qulquer forma, preciso de uma thread que rode em background, um daemon mesmo. :?
Obrigado pela ajuda por enquanto!

ViniGodoy

Quen roda seu programa, e todas as threads dele, é a vm.

Se ela finalizar, todo resto finaliza.

S

cubo:
ViniGodoy:
É justamente ao contrário. Threads deamon são feitas para não segurar a execução do programa.

Veja o que diz a documentação:
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDaemon(boolean)

The Java Virtual Machine exits when the only threads running are all daemon threads.

Quando a JVM finaliza, todas as threads daemon finalizam junto.
Isso não é só uma característica da VM, mas do SO como um todo.

Uma vez que seu programa finaliza, não dá para deixar threads para trás rodando.

ViniGodoy, imagino que daemons sejam processos que rodam em background. Dessa forma, não faz muito sentido, após o fim de meu main, os daemons morrerem junto.
Eu interpreto isso: “The Java Virtual Machine exits when the only threads running are all daemon threads.” como sendo, “Todas as não daemon morreram, então o programa principal encerra.” e não necessariamente ele mata os daemons.

E como o Samuel S disse, o programa termina quando todas as não daemon acabam, dessa forma imagino que as que são daemon, continuam rodando até o fim da execução.
De qulquer forma, preciso de uma thread que rode em background, um daemon mesmo. :?
Obrigado pela ajuda por enquanto!


Interpretou errado o que eu escrevi - as Threads marcadas daemon NÃO influenciam o termino automático da JVM!
Se todas as Threads não-daemon terminarem, a JVM será terminada mesmo se ainda tiver alguma Thread daemon rodando, portanto, com o termino da JVM, todas as Threads daemon também serão terminadas!

Praticamente significa que não está interessado em manter o programa rodando para executar apenas as Threads marcadas como daemon.
(O nome ‘daemon’ é um pouco confuso, não é a mesma funcionalidade de um processo daemon)

Exemplo: o seu programa está rodando três Threads - A é uma Thread não-daemon; X e Y são Threads daemon.
Assim que a Thread A terminar, ficariam X e Y rodando, mas essas são daemon. Como só tem Threads daemon rodando, a máquina virtual será terminada e, portanto, X e Y também serão terminadas!
É como se A fosse a principal, X e Y apenas auxiliares - o programa somente roda enquanto A não terminar.
(o System.exit() também termina a JVM, terminando todas as Threads)

ViniGodoy

Exatamente. Creio que você esteja pensando em um processo daemon.

Um processo daemon é um processo rodando. No Linux, por exemplo, você pode pelo bash transformar qualquer processo normal em um daemon, mandando ele rodar em background.

No Windows, isso é um pouco mais difícil de fazer. Você deve inicia-lo como serviço, ou usar chamadas especiais da API.

De qualquer forma, o Java não suporta uma forma multiplataforma de gerar processos daemon.

Threads são linhas de execução no interior de um processo. Elas compartilham a memória do processo entre si.
E não existem sem o processo, sejam Daemons ou não. Assim, se o processo finalizar, elas finalizam junto.

C

Agora ficou claro. Sendo assim, o que está ocorrendo com meu programa é exatamente o que deveria ocorrer.

Obrigado pessoal!

Criado 16 de abril de 2013
Ultima resposta 16 de abr. de 2013
Respostas 7
Participantes 3