您好,登錄后才能下訂單哦!
官方文檔
我們以JAVA8的doc為例
Daemon Thread VS User Thread
Java提供兩種類型的線程:用戶線程和守護(hù)程序線程。
用戶線程是高優(yōu)先級(jí)線程。 JVM將在終止任務(wù)之前等待任何用戶線程完成其任務(wù)。
守護(hù)程序線程是低優(yōu)先級(jí)線程, 其唯一作用是為用戶線程提供服務(wù)。
由于守護(hù)程序線程旨在為用戶線程提供服務(wù),并且僅在用戶線程運(yùn)行時(shí)才需要,因此一旦所有用戶線程完成執(zhí)行,它們都不會(huì)阻止JVM退出。
這也就是為什么通常存在于守護(hù)程序線程中的無(wú)限循環(huán)不會(huì)導(dǎo)致問(wèn)題,因?yàn)槿魏未a(包括finally塊)都不會(huì)在所有用戶線程完成執(zhí)行后執(zhí)行。因此,不建議將守護(hù)程序線程用于I / O任務(wù)。
但是,這條規(guī)則有例外。守護(hù)程序線程中設(shè)計(jì)糟糕的代碼可能會(huì)阻止JVM退出。例如,在正在運(yùn)行的守護(hù)程序線程上調(diào)用Thread.join()可以阻止應(yīng)用程序的關(guān)閉。
Daemon thread的特點(diǎn)
當(dāng)所有用戶線程完成執(zhí)行時(shí),它們無(wú)法阻止JVM退出。
當(dāng)所有用戶線程完成執(zhí)行時(shí),JVM會(huì)自行終止
如果JVM發(fā)現(xiàn)正在運(yùn)行的守護(hù)程序線程,它將終止該線程并在該關(guān)閉后自行終。 JVM不關(guān)心守護(hù)程序線程是否正在運(yùn)行。
這是一個(gè)極低優(yōu)先級(jí)的線程。
方法
void setDaemon(boolean status)
public final void setDaemon(boolean on)
parameters:
on : if true, marks this thread as a daemon thread.
exceptions:
IllegalThreadStateException: if only this thread is active.
SecurityException: if the current thread cannot modify this thread.
此方法用于將當(dāng)前線程標(biāo)記為守護(hù)程序線程或用戶線程。
舉個(gè)例子:
如果有一個(gè)用戶線程tU,那么tU.setDaemon(true)會(huì)使它成為守護(hù)程序線程
如果有一個(gè)守護(hù)程序線程tD,那么通過(guò)調(diào)用tD.setDaemon(false)會(huì)使它成為用戶線程。
boolean isDaemon()
public final boolean isDaemon()
returns:
This method returns true if this thread is a daemon thread;
false otherwise
此方法用于檢查當(dāng)前是守護(hù)進(jìn)程。 如果線程是守護(hù)進(jìn)程,則返回true,否則返回false。
Exceptions in Daemon thread
如果在啟動(dòng)線程后調(diào)用setDaemon()方法,則會(huì)拋出IllegalThreadStateException。
package com.artisan.test;
public class DaemonThread extends Thread {
public void run()
{
System.out.println("Thread name: " + Thread.currentThread().getName());
System.out.println("Check if its DaemonThread: "
+ Thread.currentThread().isDaemon());
}
public static void main(String[] args)
{
DaemonThread t1 = new DaemonThread();
DaemonThread t2 = new DaemonThread();
t1.start();
// Exception as the thread is already started
t1.setDaemon(true);
t2.start();
}
}
例子無(wú)錫婦科醫(yī)院 http://www.xasgfk.cn/
package com.artisan.test;
import java.time.LocalDateTime;
public class DaemonThread extends Thread {
public DaemonThread(String name) {
super(name);
}
@Override
public void run() {
// Checking whether the thread is Daemon or not
if (Thread.currentThread().isDaemon()) {
try {
System.out.println(getName() + " is Daemon thread : running " + LocalDateTime.now());
// 休眠200s
Thread.sleep(200_000);
System.out.println(getName() + " is Daemon thread: over " + LocalDateTime.now());
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
System.out.println(getName() + " is User thread : running " + LocalDateTime.now());
// 休眠5s
Thread.sleep(5_000);
System.out.println(getName() + " is User thread : over " + LocalDateTime.now());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + ": running " + LocalDateTime.now());
DaemonThread t1 = new DaemonThread("t1");
DaemonThread t2 = new DaemonThread("t2");
DaemonThread t3 = new DaemonThread("t3");
// Setting user thread t1 to Daemon
t1.setDaemon(true);
// starting first 2 threads
t1.start();
t2.start();
// Setting user thread t3 to Daemon
t3.setDaemon(true);
t3.start();
System.out.println(Thread.currentThread().getName() + ": over " + LocalDateTime.now());
}
}
執(zhí)行結(jié)果
setDaemon(true) 設(shè)置為Daemon Thread
JVM將在終止任務(wù)之前等待任何用戶線程完成其任務(wù),JVM不關(guān)心守護(hù)程序線程是否正在運(yùn)行,當(dāng)用戶線程結(jié)束后將退出。 從日志中我們可以看到t2是個(gè)user thread ,休眠了5秒,t3是daemon thread 休眠200秒,但是我們看到t2 用戶線程執(zhí)行完成后,jvm就退出了,雖然t3 daemon thread 還在進(jìn)行中,這個(gè)時(shí)候t3已經(jīng)被終止了。
使用場(chǎng)景分析
心跳檢測(cè)
A ----------------------------------------------------------------------------- B
–>Daemon Thread(Health Check)
舉個(gè)例子: 當(dāng)A到B建立了一個(gè)長(zhǎng)連接 ,長(zhǎng)連接是需要發(fā)心跳的,維持這個(gè)連接。 這個(gè)時(shí)候可以在中開(kāi)啟一個(gè)Daemon Thread用于心跳檢測(cè),當(dāng)A死掉的時(shí)候,這個(gè)Daemon Thread 也會(huì)被JVM終止掉,就避免了A和B之間已經(jīng)斷開(kāi),但是心跳檢測(cè)可能報(bào)錯(cuò)了但一直不退出的情況的發(fā)生。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。