本文主要内容
- 当用户线程全部退出后,程序就将终止,即便这时仍有守护线程在运行。
- java.util.concurrent下面的线程池默认创建的都是用户线程,包括定时调度的任务。在实际编程时,如果有一些定时运行的统计类、监控类的线程,这些线程最好设置为守护线程。
- 如何创建一个定时执行的守护线程线程池
当所有用户线程退出后,守护线程即便没有运行完,也将终止
public class Test {
public static void main(String[] args) {
//创建一个用户线程
Thread userThread=new Thread(){
public void run(){
for(int i=1;i<=5;i++){
try {
Thread.sleep(200);
System.out.println("用户线程第"+i+"次运行.....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("用户线程退出.....");
}
};
//创建一个用户模拟守护线程的线程
Thread daemonThread=new Thread(){
public void run(){
for(int i=1;i<=99999;i++){
try {
Thread.sleep(50);
System.out.println("守护线程第"+i+"次运行.....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("守护线程退出.....");
}
};
//让daemonThread成为守护线程
daemonThread.setDaemon(true);//这里必须在启动前设置,如果不设置,默认人是用户线程
userThread.start();
daemonThread.start();
System.out.println("Main exit");
}
}
程序输出
Main exit
守护线程第1次运行.....
守护线程第2次运行.....
守护线程第3次运行.....
用户线程第1次运行.....
守护线程第4次运行.....
守护线程第5次运行.....
守护线程第6次运行.....
守护线程第7次运行.....
用户线程第2次运行.....
守护线程第8次运行.....
守护线程第9次运行.....
守护线程第10次运行.....
守护线程第11次运行.....
用户线程第3次运行.....
守护线程第12次运行.....
守护线程第13次运行.....
守护线程第14次运行.....
守护线程第15次运行.....
用户线程第4次运行.....
守护线程第16次运行.....
守护线程第17次运行.....
守护线程第18次运行.....
守护线程第19次运行.....
用户线程第5次运行.....
用户线程退出.....
使用Java定时线程池的情况
结论: java线程池默认创建的都是用户线程,主线程退出后,程序还将继续运行
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);
executorService.scheduleWithFixedDelay(() -> {
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
},1, 1, TimeUnit.SECONDS);
Thread.sleep(3000);
System.out.println("Main Exit");
}
}
程序输出
2019-12-21T13:47:58.590
2019-12-21T13:47:59.592
Main Exit
2019-12-21T13:48:00.596
2019-12-21T13:48:01.601
2019-12-21T13:48:02.605
2019-12-21T13:48:03.610
2019-12-21T13:48:04.612
2019-12-21T13:48:05.615
线程池使用守护线程
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
});
executorService.scheduleWithFixedDelay(() -> {
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
},1, 1, TimeUnit.SECONDS);
Thread.sleep(10000);
System.out.println("Main Exit");
}
}
2019-12-21T13:45:53.966
2019-12-21T13:45:54.972
2019-12-21T13:45:55.975
2019-12-21T13:45:56.980
2019-12-21T13:45:57.985
2019-12-21T13:45:58.988
2019-12-21T13:45:59.993
2019-12-21T13:46:00.998
2019-12-21T13:46:02.003
Main Exit
Process finished with exit code 0