有人可以告诉我Java中有哪些守护程序线程吗?
有人可以告诉我Java中有哪些守护程序线程吗?
Answers:
守护程序线程是在程序完成但线程仍在运行时不会阻止JVM退出的线程。守护程序线程的一个示例是垃圾回收。
您可以使用该setDaemon(boolean)
方法Thread
在线程启动之前更改守护程序属性。
setDamon(boolean)
只能在启动线程之前调用它。默认情况下,线程继承其父线程的守护程序状态。
thread that does not prevent the JVM from exiting when the program finishes but the thread is still running
基本上意味着启动线程的JVM进程并不关心守护程序线程是否完成执行,如果所有正常线程都已完成执行,它将结束自身。
还有几点(参考:Java并发实践)
当所有非守护程序线程完成时,JVM暂停,所有剩余的守护程序线程都被放弃:
因此,应谨慎使用守护程序线程,将其用于可能执行任何I / O的任务是危险的。
finally
无论线程是否是守护程序,都不会执行任何块。因此,System.exit(…)
如果您认为可能有正在运行的线程正在执行I / O,请不要调用。唯一的区别是,仅保留守护程序线程时,JVM将触发自己的终止。
以上所有答案都是好的。这是一个简单的小代码段,以说明区别。尝试使用中的true和false的每个值setDaemon
。
public class DaemonTest {
public static void main(String[] args) {
new WorkerThread().start();
try {
Thread.sleep(7500);
} catch (InterruptedException e) {
// handle here exception
}
System.out.println("Main Thread ending") ;
}
}
class WorkerThread extends Thread {
public WorkerThread() {
// When false, (i.e. when it's a user thread),
// the Worker thread continues to run.
// When true, (i.e. when it's a daemon thread),
// the Worker thread terminates when the main
// thread terminates.
setDaemon(true);
}
public void run() {
int count = 0;
while (true) {
System.out.println("Hello from Worker "+count++);
try {
sleep(5000);
} catch (InterruptedException e) {
// handle exception here
}
}
}
}
守护程序线程就像其他进程或与守护程序线程在同一进程中运行的对象的服务提供程序一样。守护程序线程用于后台支持任务,仅在执行正常线程时才需要。如果正常线程未在运行,而其余线程是守护程序线程,则解释器退出。
例如,HotJava浏览器最多使用四个名为“ Image Fetcher”的守护程序线程从文件系统或网络中获取任何需要一个线程的图像。
守护程序线程通常用于为您的应用程序/小程序执行服务(例如加载“小提琴位”)。用户线程和守护程序线程之间的核心区别在于,JVM将仅在所有用户线程终止后才关闭程序。当不再运行任何用户线程(包括执行主线程)时,JVM将终止守护程序线程。
setDaemon(true / false)?此方法用于指定线程是守护程序线程。
公共布尔isDaemon()?此方法用于确定线程是否是守护程序线程。
例如:
public class DaemonThread extends Thread {
public void run() {
System.out.println("Entering run method");
try {
System.out.println("In run Method: currentThread() is" + Thread.currentThread());
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException x) {}
System.out.println("In run method: woke up again");
}
} finally {
System.out.println("Leaving run Method");
}
}
public static void main(String[] args) {
System.out.println("Entering main Method");
DaemonThread t = new DaemonThread();
t.setDaemon(true);
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException x) {}
System.out.println("Leaving main method");
}
}
输出:
C:\java\thread>javac DaemonThread.java
C:\java\thread>java DaemonThread
Entering main Method
Entering run method
In run Method: currentThread() isThread[Thread-0,5,main]
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
Leaving main method
C:\j2se6\thread>
后台进程处理诸如打印假脱机和文件传输之类的服务请求,并且在不需要时处于休眠状态。
-来源:牛津词典提供的英语
一个守护线程是被认为做了一些任务,这样可以在应用程序中存在处理请求或各种chronjobs后台线程。
当您的程序仅剩下守护程序线程时,它将退出。这是因为通常这些线程与普通线程一起工作并提供事件的后台处理。
您可以使用方法将a指定Thread
为守护程序setDaemon
,它们通常不退出,也不会被中断..它们只会在应用程序停止时停止。
我想澄清一个误解:
Java有一种特殊的线程,称为守护程序线程。
守护程序线程有什么用?
通常用作普通线程的服务提供者。通常有一个无限循环,等待服务请求或执行线程的任务。他们不能做重要的工作。(因为我们不知道它们什么时候有CPU时间,并且如果没有其他线程在运行,它们可以在任何时间完成。)
此类线程的典型示例是Java垃圾收集器。
还有更多...
setDaemon()
之前先调用方法start()
方法。线程运行后,您将无法修改其守护程序状态。isDaemon()
方法检查线程是守护程序线程还是用户线程。Java中的守护程序线程是那些在后台运行并主要由JVM创建的线程,用于执行后台任务,例如垃圾回收和其他内部任务。
注意事项:
默认情况下,由主线程创建并在Java中运行main方法的任何线程都是非守护程序,因为Thread会从创建它的线程(即父线程)继承其守护进程性质,并且由于主线程是非守护程序线程,因此从其创建的任何其他线程都会保持非守护进程,直到通过调用setDaemon(true)显式创建守护程序为止。
Thread.setDaemon(true)创建一个Thread守护程序,但是只能在以Java启动Thread之前调用它。如果相应的线程已经启动并且正在运行,它将抛出IllegalThreadStateException。
Java中Daemon和Non Daemon线程之间的区别:
1)JVM在存在之前不等待任何守护进程线程完成。
2)当JVM终止时,守护进程线程与用户线程的处理方式有所不同,最终不会调用块,不会取消堆栈堆栈,而只是退出JVM。
在Java中,守护程序线程是不会阻止Java虚拟机(JVM)退出的线程类型之一。守护程序线程的主要目的是执行后台任务,尤其是在某些例行定期任务或工作的情况下。随着JVM退出,守护程序线程也消失了。
通过设置a thread.setDaemon(true)
,线程成为守护程序线程。但是,您只能在线程启动之前设置此值。
这是一个示例,用于在由于用户线程不存在而导致jvm退出的情况下测试守护程序线程的行为。
请注意下面输出中的倒数第二行,当主线程退出时,守护线程也死了,并且在finally块中没有打印finally execute9语句。这意味着,如果由于用户线程不存在而导致JVM退出,则守护程序线程的finally块中关闭的所有I / O资源都不会关闭。
public class DeamonTreadExample {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
int count = 0;
while (true) {
count++;
try {
System.out.println("inside try"+ count);
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println("finally executed"+ count);
}
}
});
t.setDaemon(true);
t.start();
Thread.currentThread().sleep(10000);
System.out.println("main thread exited");
}
}
inside try1
finally executed1
inside try2
finally executed2
inside try3
finally executed3
inside try4
finally executed4
inside try5
finally executed5
inside try6
finally executed6
inside try7
finally executed7
inside try8
finally executed8
inside try9
finally executed9
inside try10
main thread exited
守护进程线程是众所周知的,不会限制JVM退出,因此从退出的角度来看,它基本上是Application的一个快乐线程。
想要补充一点,当我提供一个API(例如将数据推送到第三方服务器/或JMS)时,可以使用守护程序线程,我可能需要在客户端JVM级别聚合数据,然后在单独的线程中将其发送到JMS。如果这不是要推送到服务器的必需数据,则可以将该线程作为守护程序线程。这种数据就像日志推送/聚合。
问候,Manish
守护线程就像守护进程一样,负责管理资源,Java VM创建了一个守护线程来服务用户线程。Unix,unix的示例更新系统是守护进程。守护程序线程的子代始终是守护程序线程,因此默认情况下,守护程序为false。您可以使用“ isDaemon()”方法以守护程序或用户身份检查线程。因此,守护程序线程或守护程序进程基本上负责管理资源。例如,当您启动jvm时,正在运行的垃圾回收器是守护进程线程,其优先级最低为1,即管理内存。只要用户线程处于活动状态,jvm仍处于活动状态,您将无法杀死守护程序线程。jvm负责杀死守护程序线程。
让我们仅以代码和工作示例进行讨论。我喜欢上面的russ的回答,但是为了消除我的任何疑问,我对此做了一些改进。我运行了两次,一次将工作线程设置为deamon true(守护线程),另一次将其设置为false(用户线程)。它确认主线程终止时守护进程线程终止。
public class DeamonThreadTest {
public static void main(String[] args) {
new WorkerThread(false).start(); //set it to true and false and run twice.
try {
Thread.sleep(7500);
} catch (InterruptedException e) {
// handle here exception
}
System.out.println("Main Thread ending");
}
}
class WorkerThread extends Thread {
boolean isDeamon;
public WorkerThread(boolean isDeamon) {
// When false, (i.e. when it's a user thread),
// the Worker thread continues to run.
// When true, (i.e. when it's a daemon thread),
// the Worker thread terminates when the main
// thread terminates.
this.isDeamon = isDeamon;
setDaemon(isDeamon);
}
public void run() {
System.out.println("I am a " + (isDeamon ? "Deamon Thread" : "User Thread (none-deamon)"));
int counter = 0;
while (counter < 10) {
counter++;
System.out.println("\tworking from Worker thread " + counter++);
try {
sleep(5000);
} catch (InterruptedException e) {
// handle exception here
}
}
System.out.println("\tWorker thread ends. ");
}
}
result when setDeamon(true)
=====================================
I am a Deamon Thread
working from Worker thread 0
working from Worker thread 1
Main Thread ending
Process finished with exit code 0
result when setDeamon(false)
=====================================
I am a User Thread (none-deamon)
working from Worker thread 0
working from Worker thread 1
Main Thread ending
working from Worker thread 2
working from Worker thread 3
working from Worker thread 4
working from Worker thread 5
working from Worker thread 6
working from Worker thread 7
working from Worker thread 8
working from Worker thread 9
Worker thread ends.
Process finished with exit code 0
守护程序线程通常称为“服务提供者”线程。这些线程不应用于执行程序代码,而应用于执行系统代码。这些线程与您的代码并行运行,但是JVM可以随时将其杀死。当JVM没有找到用户线程时,它将停止它,并且所有守护程序线程将立即终止。我们可以使用以下命令将非守护进程线程设置为守护进程:
setDaemon(true)
只要进程的其他非守护线程仍在运行,守护线程就是在后台运行的线程。因此,当所有非守护程序线程完成时,守护程序线程将终止。非守护程序线程的一个示例是运行Main的线程。通过setDaemon()
在启动线程之前调用方法将线程作为守护程序
有关更多参考:Java中的守护程序线程
对我来说,守护进程线程就像用户线程的管家一样。如果所有用户线程均已完成,则守护进程线程将不执行任何作业,并被JVM终止。我在YouTube视频中对此进行了解释。
当最后一个非守护线程执行完成时,JVM将完成工作。默认情况下,JVM将创建一个线程作为非守护进程,但是我们可以在method的帮助下将Thread设置为守护进程setDaemon(true)
。守护程序线程的一个很好的例子是GC线程,一旦所有非守护程序线程都完成,它将立即完成他的工作。
创建者线程退出时,守护程序线程死亡。
非守护程序线程(默认)甚至可以比主线程寿命更长。
if ( threadShouldDieOnApplicationEnd ) {
thread.setDaemon ( true );
}
thread.start();
join
完之后,只要主线程运行,守护进程就会保留很长时间。
Thread
javadoc的描述它们是什么:java.sun.com/javase/6/docs/api/java/lang/Thread.html