java用戶線程和守護線程

本文主要內容

  • 當用戶線程所有退出後,程序就將終止,即使這時仍有守護線程在運行。
  • 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");
    }
}

程序輸出java

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");
    }
}

程序輸出ide

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
相關文章
相關標籤/搜索