1. 程式人生 > >執行緒池ExecutorService空閒執行緒的個數

執行緒池ExecutorService空閒執行緒的個數

  • keepAliveTime:表示執行緒沒有任務執行時最多保持多久時間會終止。預設情況下,只有當執行緒池中的執行緒數大於corePoolSize時,keepAliveTime才會起作用,直到執行緒池中的執行緒數不大於corePoolSize,即當執行緒池中的執行緒數大於corePoolSize時,如果一個執行緒空閒的時間達到keepAliveTime,則會終止,直到執行緒池中的執行緒數不超過corePoolSize。但是如果呼叫了allowCoreThreadTimeOut(boolean)方法,線上程池中的執行緒數不大於corePoolSize時,keepAliveTime引數也會起作用,直到執行緒池中的執行緒數為0;
  • allowCoreThreadTimeOut預設是false,即核心執行緒不會超時關閉,除非手動關閉執行緒池才會銷燬執行緒
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(5), new ThreadPoolExecutor.CallerRunsPolicy());
        System.out.println("核心執行緒空閒超時是否關閉:" + executor.allowsCoreThreadTimeOut());//核心執行緒空閒超時是否關閉:false
        for (int i = 0; i < 15; i++) {
            MyTask myTask = new MyTask(i);
            executor.execute(myTask);
            System.out.println("執行緒池中執行緒數目:" + executor.getPoolSize() + ",佇列中等待執行的任務數目:" +
                    executor.getQueue().size() + ",已執行完的任務數目:" + executor.getCompletedTaskCount());
        }
        executor.shutdown();//手動關閉執行緒池
        while (!executor.isTerminated()) {
        }
        if (executor.isTerminated()) {
            System.out.println("執行緒池中執行緒數目:" + executor.getPoolSize() + ",佇列中等待執行的任務數目:" +
                    executor.getQueue().size() + ",已執行完的任務數目:" + executor.getCompletedTaskCount());
        }
    }
}

class MyTask implements Runnable {
    private int taskNum;

    public MyTask(int num) {
        this.taskNum = num;
    }

    @Override
    public void run() {
        System.out.println("執行緒名稱:" + Thread.currentThread().getName() + ",正在執行task " + taskNum);
        try {
            Thread.currentThread().sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task " + taskNum + "執行完畢");
    }
}

輸出內容的最後是:執行緒池中執行緒數目:0,佇列中等待執行的任務數目:0,已執行完的任務數目:15

allowCoreThreadTimeOut設定為true,不手動關閉

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(5), new ThreadPoolExecutor.CallerRunsPolicy());
        System.out.println("核心執行緒空閒超時是否關閉:" + executor.allowsCoreThreadTimeOut());//核心執行緒空閒超時是否關閉:false
        executor.allowCoreThreadTimeOut(true);
        for (int i = 0; i < 15; i++) {
            MyTask myTask = new MyTask(i);
            executor.execute(myTask);
            System.out.println("執行緒池中執行緒數目:" + executor.getPoolSize() + ",佇列中等待執行的任務數目:" +
                    executor.getQueue().size() + ",已執行完的任務數目:" + executor.getCompletedTaskCount());
        }
        
        while (true) {
            System.out.println("執行緒池中執行緒數目:" + executor.getPoolSize() + ",佇列中等待執行的任務數目:" +
                    executor.getQueue().size() + ",已執行完的任務數目:" + executor.getCompletedTaskCount());
        }
    }
}

class MyTask implements Runnable {
    private int taskNum;

    public MyTask(int num) {
        this.taskNum = num;
    }

    @Override
    public void run() {
        System.out.println("執行緒名稱:" + Thread.currentThread().getName() + ",正在執行task " + taskNum);
        try {
            Thread.currentThread().sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task " + taskNum + "執行完畢");
    }
}

輸出內容的最後是:執行緒池中執行緒數目:0,佇列中等待執行的任務數目:0,已執行完的任務數目:15

allowCoreThreadTimeOut預設為false,不手動關閉

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(5), new ThreadPoolExecutor.CallerRunsPolicy());
        System.out.println("核心執行緒空閒超時是否關閉:" + executor.allowsCoreThreadTimeOut());//核心執行緒空閒超時是否關閉:false
//        executor.allowCoreThreadTimeOut(true);
        for (int i = 0; i < 15; i++) {
            MyTask myTask = new MyTask(i);
            executor.execute(myTask);
            System.out.println("執行緒池中執行緒數目:" + executor.getPoolSize() + ",佇列中等待執行的任務數目:" +
                    executor.getQueue().size() + ",已執行完的任務數目:" + executor.getCompletedTaskCount());
        }

        while (true) {
            System.out.println("執行緒池中執行緒數目:" + executor.getPoolSize() + ",佇列中等待執行的任務數目:" +
                    executor.getQueue().size() + ",已執行完的任務數目:" + executor.getCompletedTaskCount());
        }
    }
}

class MyTask implements Runnable {
    private int taskNum;

    public MyTask(int num) {
        this.taskNum = num;
    }

    @Override
    public void run() {
        System.out.println("執行緒名稱:" + Thread.currentThread().getName() + ",正在執行task " + taskNum);
        try {
            Thread.currentThread().sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task " + taskNum + "執行完畢");
    }
}
輸出內容的最後是:執行緒池中執行緒數目:5,佇列中等待執行的任務數目:0,已執行完的任務數目:15

總結:

1 如果手動shutdown,則空閒執行緒數為0
2 如果allowCoreThreadTimeOut預設為false,不手動shutdown,則空閒執行緒數為是核心執行緒數

3 如果allowCoreThreadTimeOut設定為true,不手動shutdown,則空閒執行緒數為0

參考:

https://blog.csdn.net/u010002184/article/details/80847398
https://www.cnblogs.com/dolphin0520/p/3932921.html         Java併發程式設計:執行緒池的使用
https://blog.csdn.net/lmj623565791/article/details/27250059    Java併發專題 帶返回結果的批量任務執行 CompletionService ExecutorService.invokeAll