Este artigo estuda principalmente questões relacionadas de tópicos de fundo em Java, como segue.
Eu nunca ouvi falar disso antes que existem tópicos de fundo em Java. De um modo geral, a JVM (Java Virtual Machine) geralmente inclui dois tipos de threads, a saber, threads do usuário e encadeamento de fundo. O chamado Thread Daemon refere-se a um thread que fornece um serviço comum em segundo plano quando o programa está em execução, e esse thread não é uma parte indispensável do programa. Portanto, quando todos os threads não background terminam, ou seja, quando os threads do usuário terminam, o programa termina. Ao mesmo tempo, ele matará todos os threads de fundo no processo. Por outro lado, enquanto quaisquer threads que não sejam de background ainda estejam em execução, o programa não terminará. É melhor executar main () do que um thread não backend.
Com base nesse recurso, quando todos os threads de usuário na saída da máquina virtual em execução, o Thread Daemon não possui objetos de serviço, a JVM sai.
Isso é explicado no código -fonte do JDK.
* Marca esse tópico como um thread {@linkplain #isdaemon} thread
* ou um tópico de usuário. A máquina virtual Java sai quando a única
* Os threads em execução são todos os threads Daemon.
1. Condições para iniciar um tópico de fundo:
/*O método setDaemon () deve ser chamado antes de iniciar o thread para definir este thread como um encadeamento em segundo plano. * Neste programa, depois que inserimos uma string, o thread principal parará de executar* e não há thread para o usuário que pode ser executado no programa. Portanto, o encadeamento de segundo plano será interrompido * A JVM será interrompida e os leitores interessados podem experimentá -lo */public class DaemonRunner implementa Runnable {@Override public void run () {while (true) {para (int i = 0; Daemon = new Thread (new DaemonRunner ()); daemon.Setdaemon (true); daemon.start (); scanner s = new Scanner (System.in); String String = S.NextLine (); RunTime.getRuntime (). AddShutdown (new Thread () {@@public void run () {) Saída "); tente {timeUnit.millisEconds.sleep (50);} catch (interruptedException e) {e.printStackTrace ();}}});}}}2. Todos os threads iniciados no encadeamento de segundo plano pertencem ao thread de segundo plano. Embora você não especifique explicitamente que eles são threads de fundo, eles são de fato threads de fundo.
/* Você pode determinar se o thread é um thread em segundo plano chamando o método iSdaemon (). Se for um encadeamento de segundo plano, * qualquer encadeamento que ele cria é definido automaticamente como o thread em segundo plano * Neste exemplo, o thread Daemon é definido como o modo de segundo plano e deriva muitos threads infantis. Esses threads não são definidos para o modo de fundo *, mas são de fato threads de fundo. Em seguida, o fio daemon entra em um loop infinito e chama o método de rendimento no loop* para entregar o controle a outros threads ou processos*/classe Daemon implementa runnable {private thread [] t = novo thread [10];@substituir public void run () {para (int i = 0; i <t.Length; i ++) {t [i] = {para (int i = 0; i <t.Length; Daemonspawn ()); t [i] .start (); System.out.println ("Daemonspawn" + i + "iniciado");} para (int i = 0; i <t.Length; i ++) {System.out.println ("t [" + i + "] .iSDaemon" + t [i]. {Thread.yield ();}}} classe Daemonspawn implementa runnable {@Override public void run () {while (true) {thread.yield ();}}} public class Daemons {public static void main (string [] args) {d thread d = novo (novo Daemon ()); D.SetDaemon (true); d.start (); System.out.println ("d.isdaemon () =" + d.isdaemon ()); tente {TimeUnit.Seconds.Sleep (1); // Deixe o encadeamento no fundo da startup obtém um determinado tempo de exceção. } catch (interruptedException e) {e.printStackTrace ();}}}Os resultados finais da execução são os seguintes:
d.IsdaMemon () = true
Daemonspawn 0started
Daemonspawn 1 iniciou
Daemonspawn 2 iniciou
Daemonspawn 3started
Daemonspawn 4started
Daemonspawn 5Started
Daemonspawn 6 iniciou
Daemonspawn 7started
Daemonspawn 8 iniciou
Daemonspawn 9 iniciou
t [0] .IsdaemoMontue
t [1] .IsdaemoMontue
t [2] .IsdaemoMentue
t [3] .IsdaemoMontue
t [4] .IsdaemoMontue
t [5] .IsdaemoMontue
t [6] .IsdaemoMontue
t [7] .IsdaemoMontue
t [8] .IsdaemoMontue
t [9] .IsdaemoMontue
3. Especifique um objeto ThreadFactory especificando Executors.newCachedThreadPool() . Dessa forma, também podemos definir o thread que queremos iniciar como um thread em segundo plano.
/* Neste exemplo, para este construtor estático: executores.newcachedThreadpool (new daemonThreadFactory ()* Podemos passar em um objeto ThreadFactory, para que possamos definir o thread que queremos iniciar como um thread de fundo {@thread* thread (thread runth lineReadFactory). Thread (R); T.SetDaemon (True); retornar t; Sleep, a linha principal terminará a execução. (InterruptedException e) {System.out.println ("interrompido");}} public static void main (string [] args) {executorService Exec = executores.newcachedthreadpool (new daemonhreadFactory ()); DaemonFromFactory ());} System.out.println ("Todos os Dameons iniciados"); Try {timeUnit.millisEconds.sleep (500);} catch (interruptedException e) {e.printstacktrace ();}}}}}}}}}O resultado final da saída é:
Todos os Dameons começaram
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214C1
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147D
Thread [Thread-0,5, Main] Concurrency.daemonfromfactory@144fe080
Thread [Thread-1,5, Main] Concurrency.daemonfromfactory@104FA29E
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
Thread [Thread-9,5, Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-7,5, Main] Concurrency.daemonfromfactory@25144C3E
Thread [Thread-4,5, Main] Concurrency.daemonfromfactory@288523d
Thread [Thread-6,5, Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-5,5, Main] Concurrency.daemonfromfactory@626007AA
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214C1
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147D
Thread [Thread-6,5, Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-5,5, Main] Concurrency.daemonfromfactory@626007AA
Thread [Thread-4,5, Main] Concurrency.daemonfromfactory@288523d
Thread [Thread-9,5, Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-7,5, Main] Concurrency.daemonfromfactory@25144C3E
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
Thread [Thread-1,5, Main] Concurrency.daemonfromfactory@104FA29E
Thread [Thread-0,5, Main] Concurrency.daemonfromfactory@144fe080
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147D
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214C1
Thread [Thread-6,5, Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-1,5, Main] Concurrency.daemonfromfactory@104FA29E
Thread [Thread-0,5, Main] Concurrency.daemonfromfactory@144fe080
Thread [Thread-7,5, Main] Concurrency.daemonfromfactory@25144C3E
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
Thread [Thread-5,5, Main] Concurrency.daemonfromfactory@626007AA
Thread [Thread-9,5, Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-4,5, Main] Concurrency.daemonfromfactory@288523d
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147D
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214C1
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
Thread [Thread-7,5, Main] Concurrency.daemonfromfactory@25144C3E
Thread [Thread-4,5, Main] Concurrency.daemonfromfactory@288523d
Thread [Thread-6,5, Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-1,5, Main] Concurrency.daemonfromfactory@104FA29E
Thread [Thread-0,5, Main] Concurrency.daemonfromfactory@144fe080
Thread [Thread-9,5, Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-5,5, Main] Concurrency.daemonfromfactory@626007AA
Thread [Thread-3,5, Main] Concurrency.daemonfromfactory@56214C1
Thread [Thread-2,5, Main] Concurrency.daemonfromfactory@5724147D
Thread [Thread-8,5, Main] Concurrency.daemonfromfactory@5b069a7f
4. Primeiro de tudo, você deve perceber que, se o tópico do usuário sair repentinamente, o encadeamento em segundo plano encerrará seu método de execução sem executar a cláusula finalmente.
/* Quando você chama este programa, verá que a cláusula finalmente não será executada, mas se você comentar a chamada para setDaemon (), verá que a cláusula* finalmente será executada.* Esse comportamento está correto. Mesmo se você não quiser esse comportamento com base na promessa que finalmente deu na sua frente. Mas esse é o caso. Quando o último fio que não é de background terminar, o thread de segundo plano para repentinamente. Porque uma vez que o main () sai, a JVM fechará imediatamente todos os threads * em segundo plano. Como você não pode fechar os tópicos de fundo de uma maneira elegante, eles dificilmente são uma boa ideia. Os executores que não são de backend são geralmente de uma maneira * melhor, porque todas as tarefas controladas pelo executor podem ser fechadas ao mesmo tempo. */class Adaemon implementa Runnable {@Override public void run () {System.out.println ("Iniciando Adaemon"); tente {timeunit.seconds.sleep (1); } catch (interruptedException e) {System.out.println ("Exiting via interruptedException"); } finalmente {System.out.println ("Isso sempre deve ser executado?"); }}} classe pública daemonsDontrunfinalmente {public static void main (string [] args) {thread t = new Thread (new Adaemon ()); t.SetDaemon (true); t.start (); }} Os resultados finais da saída são os seguintes:
Iniciando Adaemon
No entanto, se a situação se tornar a seguinte situação, os resultados da saída serão diferentes novamente:
classe Adaemon implementa Runnable {@Override public void run () {System.out.println ("Iniciando Adaemon"); tente {timeunit.seconds.sleep (1); } catch (interruptedException e) {System.out.println ("Exiting via interruptedException"); } finalmente {System.out.println ("Isso sempre deve ser executado?"); }}} classe pública daemonsDontrunfinalmente {public static void main (string [] args) {thread t = new Thread (new Adaemon ()); t.SetDaemon (true); t.start (); tente {timeunit.seconds.sleep (1); } catch (interruptedException e) {e.printStackTrace (); }}}Como o tópico principal não sai repentinamente, o thread de segundo plano recebe o tempo de execução durante o encadeamento principal, então o resultado final da impressão é:
Iniciando Adaemon
Isso sempre deve ser executado?
O exposto acima é todo o conteúdo deste artigo sobre a análise de instâncias de threads em Java, e espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!