守护线程什么时候有用?
我知道Deamon线程是后台线程。我们可以通过调用setDaemon(true)
来创建我们自己的守护线程。
我的问题是:为什么以及何时需要将线程创建为守护线程?
I know that Deamon threads are background threads. We can create our own daemon thread by calling setDaemon(true)
.
My question is: Why and when do we need to create our thread as a daemon thread?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
当所有正在运行的线程都是守护线程时,JVM 就会退出。因此,假设您正在编写一个简单的游戏,其中主方法会循环直到您决定退出。想象一下,在游戏开始时,您启动一个线程,该线程将无休止地轮询某些网站以触发警报。当您决定结束游戏时,您希望 JVM 退出。您不希望无休止的轮询阻止游戏结束。因此,您将此轮询线程设为守护线程。
The JVM exits when all the running threads are daemon threads. So imagine you're writing a simple game where your main method loops until you decide to quit. And imagine that at the start of the game, you start a thread that will endlessly poll some website to trigger alerts. You would like the JVM to exit when you decide to end the game. You don't want the endless polling to prevent the game from ending. So you make this polling thread a daemon thread.
当所有“正常”线程终止时,JVM 会自动终止守护线程。普通线程永远不会自动终止。
A Deamon thread is automatically terminated by the JVM when all "normal" threads are terminated. Normal threads are never automatically terminated.
您希望通过本质上用户线程向消费者提供的无需任何用户交互的服务构成了将用户线程设置为守护程序的主要用例。
因此,在用户线程存在之前,JVM 保证守护线程持续运行。您可以找到诸如 GC、UI Thread 等示例。这些都是守护进程。
希望有帮助。
Services that you wish to offer to your consumers without any user-interation by way of essentially user-threads form the primary use-case for setting a user thread as a daemon.
As a consequence, until user-threads exist JVM gurantees that daemon threads run continously. You can find examples like GC, UI Thread etc.. those are daemons.
Hope it helps.
正如其他人指出的那样,当程序完成且该线程仍在运行时,守护线程不会阻止 JVM 退出。
一般来说,您不想创建守护线程,除非您绝对确定该线程没有副作用。由于您无法判断线程何时停止,因此终结器块不会运行,也不会展开任何堆栈。因此,请尝试避免在守护线程中使用 IO 操作,因为它可能会损坏数据。
As other have pointed, a daemon thread does not prevent the JVM from exiting when the program finishes when this thread is still running.
In general you'd rather not create daemon threads, unless you are absolutely certain the thread has no side effects. Since you can't tell when the thread stops, finalizer blocks are not run, nor are any stack unwound. So try avoiding using IO operations in daemon threads because it can corrupt data.
通常,当程序的所有线程退出其
run()
方法时,程序就会终止。守护线程不会阻止程序终止,即使它们仍在运行,即执行run()
。因此,如果您不希望在线程仍在运行时阻止程序终止,则应该使用守护线程。例如,这是典型的长期周期性任务,但实际上很大程度上取决于您的程序、您的设计和您的品味。
Normally program terminates when all its threads exited their
run()
method. Daemon threads do not prevent program to terminate even if they are still running, i.e. executingrun()
.So, you should use daemon thread if you wish not to prevent program termination when the thread is still running. It is typical for example for long-time periodic tasks but actually depend very much on your program, your design and your taste.
Java 中的守护线程就像是与守护线程运行在同一进程中的其他线程或对象的服务提供者。守护线程用于后台支持任务,并且仅在普通线程执行时才需要。如果正常线程没有运行并且剩余线程是守护线程,则解释器退出。
当创建新线程时,它会继承其父线程的守护进程状态。普通线程和守护线程在退出时发生的情况有所不同。当 JVM 停止时,任何剩余的守护线程都会被放弃:finally 块不会被执行,堆栈不会展开 - JVM 只是退出。因此,应谨慎使用守护线程,将它们用于可能执行任何类型 I/O 的任务是危险的。
Daemon threads in Java are like a service providers for other threads or objects running in the same process as the daemon thread. Daemon threads are used for background supporting tasks and are only needed while normal threads are executing. If normal threads are not running and remaining threads are daemon threads then the interpreter exits.
When a new thread is created it inherits the daemon status of its parent. Normal thread and daemon threads differ in what happens when they exit. When the JVM halts any remaining daemon threads are abandoned: finally blocks are not executed, stacks are not unwound – JVM just exits. Due to this reason daemon threads should be used sparingly and it is dangerous to use them for tasks that might perform any sort of I/O.
我将它们与计时器一起使用来删除无法立即删除的文件。也就是说,我生成.exe文件,运行然后删除它们。但有 50% 的可能性
executable.delete
会失败,这似乎是因为映像在终止时仍被进程阻塞。只有在进程完全完成后,您才能可靠地删除可执行映像。但是,你永远不知道需要多长时间。因此,您设置 .deleteOnExit 而不是 .delete。但是,您不想等到 java 机器也终止。这可能需要很长时间,而且您不希望有数百万个您不再需要的无用的愚蠢 .exe 文件挂在文件系统中。因此,您可以安排计时器中的executable.delete 在一两秒后发生。然而计时器不能是普通线程。如果是这样,即使没有要删除的文件,它也会阻止您的程序终止。然而,我可以轻松地将其设置为守护进程,因为我的文件是否被计时器删除并不重要——文件将以任何方式被删除:通过守护进程或java退出。我认为这是守护进程的完美使用。I used them with Timer to delete files that cannot be deleted immediately. That is, I generate .exe files, run and then delete them. But there is 50% chance that
executable.delete
fails, seemingly because image is still blocked by the process in termination. You can reliably delete executable image only after process has finished completely. But, you never know how long it takes. You set .deleteOnExit therefore instead of .delete. But, you do not want to wait until java machine terminates also. It can take very long and you do not want millions of useless stupid .exe files, that you do not need anymore, hanging in the file system. You therefore schedule executable.delete in the timer to happen one-two seconds later. The timer however cannot be usual thread. If it is so, it will block your program from terminating even if there are no files to delete. I can easily make it daemon however because whether my files are deleted or not by timer is immaterial -- the files will be removed either way: either by daemon or java exit. I think it is perfect use of daemon.