在Java中,用户线程和守护线程有什么区别?

27

1
守护线程:https://dev59.com/j3E95IYBdhLWcg3wp_un - rai.skumar
谢谢,但你能回答问题2吗? - lichengwu
1
希望我已经回答了你的第二个问题。 - rai.skumar
1
这只是一个线程上的标志,它表示“不要为了我的缘故而继续运行”。您可以使用这样的线程进行监视,例如检查其他线程是否被阻塞。如果没有其他线程在运行,那么进行此检查就没有意义。 - Peter Lawrey
3个回答

25

当最后一个非JVM线程终止时,JVM将退出。这意味着,如果您创建的任何线程仍在运行,则JVM将不会关闭。

守护线程是不会防止JVM关闭的线程。通常,您会将它们用于一些后台任务,如果用户请求关闭应用程序,则不希望它们保持其运行。

此外,您的问题已经在此处提出(并回答)- Java中的守护线程是什么?

一些常见的(个人经验)守护线程用例可能包括:

  • 轮询远程系统以获取状态更改的后台线程
  • 后台工作线程(诸如发送电子邮件通知、SNMP等)
  • 用于执行计划维护的自定义计时器线程

谢谢,但你的主要问题是问题2。 - lichengwu
@lichengwu - 编辑回复以包括我使用它们的用途 - radai

5

第二个问题:

当所有普通线程都已终止时,守护线程将自动终止。

您可以使用守护线程在应用程序中进行一些清理工作或处理杂务。 守护线程用于后台支持任务,仅在正常线程执行时需要。 GC线程是一个守护线程。


为什么我的程序在发生GC时停止运行,而系统告诉我只有在内存不足时才会发生GC? - Val
这是一个适合在SO上提出的单独问题。现在回到你的问题上。GC浏览所有活跃对象,所以当GC运行时通常应用程序执行会被暂停,以确保其能够在一致的状态下查找对象。如果应用程序与GC同时运行,则对象可能处于不一致的状态。是的,通常当JVM感觉需要更多可用内存时才会触发GC。 - rai.skumar
当GC开始运行时,应用程序线程会被置于休眠模式。 - rai.skumar
当您的GC线程仅在其他线程处于休眠状态时处于活动状态时,这意味着您不需要GC线程。这根本不是多线程。线程是为了同时运行进程而需要的。我的意思是,GC是一个糟糕的守护进程示例。您可以将其优化掉。 - Val
不同意你的评论..也许你可以提出一个单独的问题。 - rai.skumar

2
用户线程是应用程序(用户)创建的线程,而大多数情况下,守护线程是由Java虚拟机创建的,以服务于用户线程。当用户线程退出时,虚拟机会区分线程类型,即用户线程或守护线程。如果存在其他用户线程,则在用户线程退出时,虚拟机将检查是否有其他用户线程正在运行。如果有,则调度下一个线程(用户线程或守护线程)。如果没有其他用户线程运行,只有守护线程,那么该虚拟机实例也将退出。
这两种类型线程的区别很明显:如果Java运行时确定应用程序中唯一运行的线程是守护线程(即不存在用户线程),则Java运行时会立即关闭应用程序,有效地停止所有守护线程。为了使应用程序继续运行,它必须始终至少有一个活动的用户线程。在其他方面,Java运行时以完全相同的方式处理守护线程和用户线程。

当调用 System.exit(0) 时,主线程和用户线程将停止,但JVM将如何处理守护线程?忽略?停止?还是杀死? - lichengwu
1
@lichengwu - system.exit()会立即停止所有操作。区别在于更优雅的退出方式——就像当您的main()方法结束时发生的那样。 - radai
@radai +1. 当JVM退出时,它会先停止用户线程,然后再停止守护线程吗? - lichengwu
@lichengwu - 我认为他们不会保证顺序。如果您打算编写自己的关闭逻辑,请在正确关闭所有内容之后再使用System.exit()。 - radai
@radai 嗯,JVM停止不仅包括system.exit。你知道在关闭JVM时,它是否会按顺序停止用户线程和守护线程吗? - lichengwu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接