ThreadPoolExecutor 中的 shutdown() 、awaitTermination() 、 shutdownNow() 的用法


shutdown和awaitTermination為接口ExecutorService定義的兩個方法,一般情況配合使用來關閉線程池。

方法簡介
shutdown方法:將線程池狀態置為SHUTDOWN。平滑的關閉ExecutorService,當此方法被調用時,ExecutorService停止接收新的任務並且等待已經提交的任務(包含提交正在執行和提交未執行)執行完成。當所有提交任務執行完畢,線程池即被關閉。

awaitTermination方法:接收人timeout和TimeUnit兩個參數,用於設定超時時間及單位。當等待超過設定時間時,會監測ExecutorService是否已經關閉,若關閉則返回true,否則返回false。一般情況下會和shutdown方法組合使用。

shutdownNow方法:將線程池狀態置為STOP。跟shutdown()一樣,先停止接收外部提交的任務,忽略隊列里等待的任務,嘗試將正在跑的任務interrupt中斷,返回未執行的任務列表。

具體實例1
普通任務處理類:

package com.secbro.test.thread;

import java.util.concurrent.Callable;

/**
 * @author zhuzhisheng
 * @Description
 * @date on 2016/6/1.
 */
public class Task implements Callable{
    @Override
    public Object call() throws Exception {
        System.out.println("普通任務");
        return null;
    }
}

長時間任務處理類:

package com.secbro.test.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 * @author zhuzhisheng
 * @Description
 * @date on 2016/6/1.
 */
public class LongTask implements Callable{
    @Override
    public Object call() throws Exception {
        System.out.println("長時間任務");
        TimeUnit.SECONDS.sleep(5);
        return null;
    }
}

測試類:

package com.secbro.test.thread;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author zhuzhisheng
 * @Description
 * @date on 2016/6/1.
 */
public class TestShutDown {

    public static void main(String[] args) throws InterruptedException{
        ScheduledExecutorService service = Executors.newScheduledThreadPool(4);

        service.submit(new Task());
        service.submit(new Task());
        service.submit(new LongTask());
        service.submit(new Task());


        service.shutdown();

        while (!service.awaitTermination(1, TimeUnit.SECONDS)) {
            System.out.println("線程池沒有關閉");
        }

        System.out.println("線程池已經關閉");
    }

}

輸出結果為:

普通任務
普通任務
長時間任務
普通任務
線程池沒有關閉
線程池沒有關閉
線程池沒有關閉
線程池沒有關閉
線程池已經關閉

 

具體實例2

public class ThreadPoolHelper {

    private static final Logger logger = Logger.getLogger(ThreadPoolHelper.class);

    private static final int POOL_SIZE = 40;//線程池大小

    //訂單任務線程池

    private static ThreadPoolExecutor comitTaskPool =(ThreadPoolExecutor) new ScheduledThreadPoolExecutor(POOL_SIZE,
            new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());


    /**
     * 執行訂單任務
     *
     * @param comitTask
     */
    public static void executeTask(Runnable comitTask) {
        comitTaskPool.execute(comitTask);
        logger.debug("【線程池任務】線程池中線程數:" + comitTaskPool.getPoolSize());
        logger.debug("【線程池任務】隊列中等待執行的任務數:" + comitTaskPool.getQueue().size());
        logger.debug("【線程池任務】已執行完任務數:" + comitTaskPool.getCompletedTaskCount());
    }


    /**
     * 關閉線程池
     */
    public static void shutdown() {
        logger.debug("shutdown comitTaskPool...");
        comitTaskPool.shutdown();
        try {
            if (!comitTaskPool.isTerminated()) {
                logger.debug("直接關閉失敗[" + comitTaskPool.toString() + "]");
                comitTaskPool.awaitTermination(3, TimeUnit.SECONDS);
                if (comitTaskPool.isTerminated()) {
                    logger.debug("成功關閉[" + comitTaskPool.toString() + "]");
                } else {
                    logger.debug("[" + comitTaskPool.toString() + "]關閉失敗,執行shutdownNow...");
                    if (comitTaskPool.shutdownNow().size() > 0) {
                        logger.debug("[" + comitTaskPool.toString() + "]沒有關閉成功");
                    } else {
                        logger.debug("shutdownNow執行完畢,成功關閉[" + comitTaskPool.toString() + "]");
                    }
                }
            } else {
                logger.debug("成功關閉[" + comitTaskPool.toString() + "]");
            }
        } catch (InterruptedException e) {
            logger.warn("接收到中斷請" + comitTaskPool.toString() + "停止操作");
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM