1. 程式人生 > >Java多線程系列七——ExecutorService

Java多線程系列七——ExecutorService

blocking nat get() all 固定 unit emp rep integer

java.util.concurrent.ExecutorService接口提供了許多線程管理的方法

Method 說明
shutdown 拒絕接收新的任務,待已提交的任務執行後關閉,且宿主線程不阻塞,若需要阻塞可借助awaitTermination實現
shutdownNow 停止所有正在執行的任務,掛起未執行的任務並關閉,且宿主線程不阻塞,若需要阻塞可借助awaitTermination實現
awaitTermination 當發生shutdown時,阻塞宿主線程直到約定的時間已過或者所有任務完成
submit 提交任務Callable/Runnable,可利用Future的get()方法使宿主線程阻塞直到任務結束後返回結果

有了以上方法,便可以基於此接口實現線程池的各種功能(例如java.util.concurrent.ThreadPoolExecutor/java.util.concurrent.ScheduledThreadPoolExecutor),以java.util.concurrent.ThreadPoolExecutor為例,其參數的詳解

Name Type 說明
corePoolSize int 線程池中最小的線程數
maximumPoolSize int 線程池中最大的線程數
keepAliveTime long 線程空閑時間,若線程數大於corePoolSize,空閑時間超過該值的線程將被終止回收
unit TimeUnit keepAliveTime的時間單位
workQueue BlockingQueue<Runnable> 已提交但未執行的任務隊列
threadFactory ThreadFactory 創建新線程的工廠
handler RejectedExecutionHandler 當線程池或隊列達到上限拒絕新任務拋出異常時的處理類

同時,java.util.concurrent.Executors類提供了基於java.util.concurrent.ThreadPoolExecutor類的工具方法,常用方法有

Method 說明
newFixedThreadPool 線程池中含固定數量的線程
newSingleThreadExecutor 線程池中僅含一個工作線程
newCachedThreadPool 按需創建線程,若線程池中無可用線程,則創建新的線程並加入,直到線程數達到上限值(Integer.MAX_VALUE)

測試代碼如下

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.junit.Assert;
import org.junit.Test;

/**
 * @Description: 測試ExecutorService
 */
public class ThreadExecutorServiceTest {
    private static final String THIS_IS_SHUTDOWN_WITH_AWAIT_TERMINATION = "This is shutdownWithAwaitTermination";
    private static final int RESULT = 111;

    private static boolean submitRunnable() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        Future<?> future = executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("This is submitRunnable");
            }
        });
        return future.get() == null;
    }

    private static Integer submitRunnableWithResult() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        Future<Integer> future = executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("This is submitRunnableWithResult");
            }
        }, RESULT);
        return future.get();
    }

    private static Integer submitBlockCallable() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future<Integer> future = executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("This is submitBlockCallable");
                return RESULT;
            }
        });
        return future.get();// 阻塞
    }

    private static boolean submitNonBlockCallable() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future<Integer> future = executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("This is submitNonBlockCallable");
                return RESULT;
            }
        });
        while (!future.isDone()) {// 非阻塞
            System.out.println(new Date());
        }
        return future.isDone();
    }

    private static String shutdown() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        final StringBuilder sb = new StringBuilder();
        executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                Thread.sleep(10000);
                sb.append("This is shutdown");
                return RESULT;
            }
        });
        executorService.shutdown();
        return sb.toString();
    }

    private static String shutdownWithAwaitTermination() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        final StringBuilder sb = new StringBuilder();
        executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                Thread.sleep(10000);
                sb.append(THIS_IS_SHUTDOWN_WITH_AWAIT_TERMINATION);
                return RESULT;
            }
        });
        executorService.shutdown();
        executorService.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);
        return sb.toString();
    }

    @Test
    public void test() throws InterruptedException, ExecutionException {
        Assert.assertTrue(submitRunnable());
        Assert.assertEquals(RESULT, submitRunnableWithResult().intValue());
        Assert.assertEquals(RESULT, submitBlockCallable().intValue());
        Assert.assertTrue(submitNonBlockCallable());
        Assert.assertTrue(shutdown().isEmpty());
        Assert.assertEquals(THIS_IS_SHUTDOWN_WITH_AWAIT_TERMINATION, shutdownWithAwaitTermination());
    }

}

Java多線程系列七——ExecutorService