ThreadPoolExecutor常用方法

一 线程池中线程数量

ThreadPoolExecutor类中线程数量相关方法

ThreadPoolExecutor常用方法_第1张图片

public int getCorePoolSize():the core number of threads,核心线程数,固定值;
public int getMaximumPoolSize():the maximum allowed number of threads,最大线程数,固定值;
public int getPoolSize():the current number of threads in the pool,线程池中线程的数量;
public int getLargestPoolSize():the largest number of threads that have ever simultaneously been in the pool,线程池中线程最多时的数量;
public int getActiveCount():the approximate number of threads that are actively executing tasks,正在执行任务的线程数量(近似值);
public long getCompletedTaskCount():the approximate total number of tasks that have completed execution,任务执行完成的数量(近似值);
public long getTaskCount():the approximate total number of tasks that have ever been scheduled for execution,计划执行任务的数量,包括正在执行任务和已经完成的任务(近似值);

static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 1,
        TimeUnit.SECONDS, 
        new ArrayBlockingQueue<>(1), 
        new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) throws InterruptedException {
    testPoolBasicInfo();
    for (int i = 0; i < 5; i++) {
        threadPoolExecutor.execute(() -> {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    Thread.sleep(2000);
    testPoolBasicInfo();
    for (int i = 0; i < 2; i++) {
        threadPoolExecutor.execute(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    testPoolBasicInfo();
    threadPoolExecutor.shutdown();
}
public static void testPoolBasicInfo() {
    System.out.println("threadPoolExecutor.getCorePoolSize() = "
            + threadPoolExecutor.getCorePoolSize());
    System.out.println("threadPoolExecutor.getMaximumPoolSize() = "
            + threadPoolExecutor.getMaximumPoolSize());
    System.out.println("threadPoolExecutor.getPoolSize() = "
            + threadPoolExecutor.getPoolSize());
    System.out.println("threadPoolExecutor.getLargestPoolSize() = "
            + threadPoolExecutor.getLargestPoolSize());
    System.out.println("threadPoolExecutor.getActiveCount() = "
            + threadPoolExecutor.getActiveCount());
    System.out.println("threadPoolExecutor.getTaskCount() = "
            + threadPoolExecutor.getTaskCount());
    System.out.println("threadPoolExecutor.getCompletedTaskCount() = "
            + threadPoolExecutor.getCompletedTaskCount());
}

二 线程池的submit()方法

Future submit(Runnable task):实现父接口ExecutorService的方法,用于执行Runnable接口的任务,方法返回值是null;
Future submit(Runnable task, T result):实现父接口ExecutorService的方法,用于执行Runnable接口的任务,方法返回第二个参数result的值;
Future submit(Callable task):实现父接口ExecutorService的方法,用于执行Callable接口的任务,方法返回值是call()方法返回的值;

2.1 submit()方法正常使用

public static void main(String[] args) throws InterruptedException, ExecutionException {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1), new ThreadPoolExecutor.AbortPolicy());
    Runnable r1 = () -> {
        System.out.println("runnable...");
    };
    Callable c1 = () -> {
        System.out.println("callable...");
        return "callable success";
    };
    // 返回null
    Future future1 = threadPoolExecutor.submit(r1);
    // 返回call()方法返回值
    Future future2 = threadPoolExecutor.submit(c1);
    // 返回第二个参数result的值
    Future future3 = threadPoolExecutor.submit(r1, "success");
    // 返回第二个参数result的值
    Future future4 = threadPoolExecutor.submit(r1, 123);
    Object obj1 = future1.get();
    String str2 = future2.get();
    String str3 = future3.get();
    Integer int4 = future4.get();
    System.out.println("obj1 is: " + obj1);
    System.out.println("str2 = " + str2);
    System.out.println("str3 = " + str3);
    System.out.println("int4 = " + int4);
    // runnable...
    // runnable...
    // callable...
    // runnable...
    // obj1 is: null
    // str2 = callable success
    // str3 = success
    // int4 = 123
}

2.2 submit()方法出现异常

执行任务方法出现的异常有三种:
        ExecutionException,任务执行异常
        TimeoutException,获取任务结果超时异常
        InterruptedException,线程中断异常

2.2.1 ExecutionException

如果线程任务执行异常,那么当前任务的后续代码不会执行,调用线程池的线程(譬如主线程)会抛出异常,Future的get()方法后面的代码不会执行

public static void main(String[] args)  {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1),
            new ThreadPoolExecutor.AbortPolicy());
    Runnable r1 = () -> {
        System.out.println("runnable one...");
        // 模拟任务执行异常
        System.out.println(1 / 0);
        System.out.println("runnable one one...");
    };
    Future future1 = threadPoolExecutor.submit(r1);
    try {
        // 任务执行异常, 当前任务的后续代码不会执行,
        // 调用线程池的线程(譬如主线程)会抛出异常, Future的get()方法后面的代码不会执行;
        // 如果不执行future1.get()方法, 不获取异步执行结果, 线程任务的异常不会抛出;
        Object obj1 = future1.get();
        System.out.println("main线程此处代码能否执行到...");
        System.out.println("obj1 is: " + obj1);
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    } finally {
        threadPoolExecutor.shutdown();
    }
    // runnable one...
    // java.util.concurrent.ExecutionException:
}

2.2.2 TimeoutException

如果线程任务结果获取超时异常,那么当前任务的后续代码会执行完,而且调用线程池的线程(譬如主线程)会抛出异常,Future的get()方法后面的代码不会执行

public static void main(String[] args) {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60, 
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1), 
            new ThreadPoolExecutor.AbortPolicy());
    Runnable r1 = () -> {
        System.out.println("runnable one...");
        // 模拟任务执行耗时
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("runnable one one...");
    };
    Future future1 = threadPoolExecutor.submit(r1);
    try {
        // 任务结果获取超时异常, 当前任务的后续代码会执行完, 
        // 调用线程池的线程(譬如主线程)会抛出异常,
        // Future的get()方法后面的代码不会执行;
        Object obj1 = future1.get(3, TimeUnit.SECONDS);
        System.out.println("main线程此处代码能否执行到...");
        System.out.println("obj1 is: " + obj1);
    } catch (InterruptedException | TimeoutException | ExecutionException e) {
        e.printStackTrace();
    } finally {
        threadPoolExecutor.shutdown();
    }
    // runnable one...
    // java.util.concurrent.TimeoutException
    //   at java.util.concurrent.FutureTask.get(FutureTask.java:205)
    //  at com.mango.executors.ThreadPoolExecutorDemo.main(ThreadPoolExecutorDemo.java:24)
    // runnable one one...
}

2.2.3 InterruptedException

如果出现线程中断异常,那么当前任务的后续代码会执行完,而且调用线程池的线程(譬如主线程)会抛出异常,Future的get()方法后面的代码会执行完

public static void main(String[] args) {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1),
            new ThreadPoolExecutor.AbortPolicy());
    Runnable r1 = () -> {
        System.out.println("runnable one...");
        // 模拟线程中断
        try {
            Thread.currentThread().interrupt();
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
            threadPoolExecutor.shutdown();
        }
        System.out.println("runnable one one...");
    };
    Future future1 = threadPoolExecutor.submit(r1);
    // 线程中断异常, 当前任务的后续代码会执行完, 
    // 调用线程池的线程(譬如主线程)会抛出异常, 
    // Future的get()方法后面的代码会执行完;
    try {
        Object obj1 = future1.get();
        System.out.println("main线程此处代码能否执行到...");
        System.out.println("obj1 is: " + obj1);
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    } finally {
        threadPoolExecutor.shutdown();
    }
    // runnable one...
    // runnable one one...
    // main线程此处代码能否执行到...
    // obj1 is: null
    // java.lang.InterruptedException: sleep interrupted
}

三 线程池的execute()方法

public void execute(Runnable command):实现父接口Executor的方法,用于执行Runnable接口的任务,方法无返回值

3.1 execute()方法正常使用

public static void main(String[] args)  {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60, 
        TimeUnit.SECONDS,
        new ArrayBlockingQueue<>(1), 
        new ThreadPoolExecutor.AbortPolicy());
    Runnable r1 = () -> {
        System.out.println("runnable one...");
    };
    try {
        threadPoolExecutor.execute(r1);
        System.out.println("main线程执行的任务");
    } finally {
        threadPoolExecutor.shutdown();
    }
}

3.2 execute()方法出现异常

执行任务方法出现的异常有两种:
        ExecutionException,任务执行异常
        InterruptedException,线程中断异常

3.2.1 ExecutionException

如果任务执行异常,那么当前任务的后续代码不会执行,而且调用线程池的线程(譬如主线程)会抛出异常,但是代码会执行完

public static void main(String[] args)  {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60, 
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1), 
            new ThreadPoolExecutor.AbortPolicy());
    Runnable r1 = () -> {
        System.out.println("runnable one...");
        // 模拟任务执行异常
        System.out.println(1/0);
        System.out.println("runnable one one...");
    };
    try {
        System.out.println("aaa");
        // 任务执行异常, 当前任务的后续代码不会执行, 
        // 调用线程池的线程(譬如主线程)会抛出异常, 但是代码会执行完;
        threadPoolExecutor.execute(r1);
        System.out.println("bbb");
    } finally {
        threadPoolExecutor.shutdown();
    }
}

3.2.2 InterruptedException

如果是线程中断异常,那么当前任务的后续代码会执行完,而且调用线程池的线程(譬如主线程)会抛出异常,但是代码会执行完

public static void main(String[] args)  {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60, 
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1), 
            new ThreadPoolExecutor.AbortPolicy());
    Runnable r1 = () -> {
        System.out.println("runnable one...");
        // 模拟中断异常
        try {
            Thread.currentThread().interrupt();
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("runnable one one...");
    };
    try {
        System.out.println("aaa");
        // 线程中断异常, 当前任务的后续代码会执行完, 
        // 调用线程池的线程(譬如主线程)会抛出异常, 但是代码会执行完;
        threadPoolExecutor.execute(r1);
        System.out.println("bbb");
    } finally {
        threadPoolExecutor.shutdown();
    }
}

四 线程池的invokeAll()方法

public List> invokeAll(Collection> tasks):
        继承AbstractExecutorService类的方法,是阻塞方法,等到所有任务执行完成才返回;
        invokeAll方法执行完成任务结果的顺序是和任务放入集合中的顺序一致的;
        如果某个任务出现异常,那么此任务之前的任务正常输出,此任务后面的任务不输出,而且调用线程池的线程(譬如主线程)也不会输出内容;

public static void main(String[] args) throws InterruptedException, ExecutionException {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60, 
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1), 
            new ThreadPoolExecutor.AbortPolicy());
    Callable c1 = () -> {
        System.out.println("callable one...");
        Thread.sleep(100);
        return "callable success one";
    };
    Callable c2 = () -> {
        System.out.println("callable two...");
        Thread.sleep(1000);
        System.out.println(1 / 0);
        return "callable success two";
    };
    Callable c3 = () -> {
        System.out.println("callable three...");
        Thread.sleep(5000);
        return "callable success three";
    };
    List> callableList = new ArrayList<>();
    callableList.add(c1);
    callableList.add(c2);
    callableList.add(c3);
    // invokeAll()方法是阻塞方法, 等到所有任务执行完成才返回;
    // 任务执行结果的顺序是依据任务放入集合中的顺序;
    // 如果某个任务出现异常, 那么此任务之前的任务正常输出;
    // 如果某个任务出现异常, 那么此任务后面的任务不输出, 而且调用线程池的线程也不会输出内容;
    try {
        List> futureList = threadPoolExecutor.invokeAll(callableList);
        for (Future future : futureList) {
            System.out.println("future.isCancelled() = " + future.isCancelled());
            System.out.println("future.isDone() = " + future.isDone());
            System.out.println("result is: " + future.get());
        }
    } finally {
        threadPoolExecutor.shutdown();
    }
    System.out.println("主线程方法什么时候执行... ...");
    // callable one...
    // callable three...
    // callable two...
    // future.isCancelled() = false
    // future.isDone() = true
    // result is: callable success one
    // future.isCancelled() = false
    // future.isDone() = true
    // Exception in thread "main" java.util.concurrent.ExecutionException
}

五 线程池的invokeAny()方法

public T invokeAny(Collection> tasks):
        继承AbstractExecutorService类的方法,是阻塞方法,只需要等待任意一个任务执行完成并返回任务结果,并且会取消其他任务的执行;
        invokeAny()方法的返回值是Callable接口的call()方法返回值;
        invokeAny()方法执行的任务列表中的某一个任务抛出异常,就会抛弃当前任务,并执行下一个任务;
        invokeAny()方法执行的任务列表中的所有任务都抛出异常,那么调用当前线程池任务的线程(譬如主线程)也会抛出异常;

public static void main(String[] args) throws InterruptedException, ExecutionException {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60, 
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1), 
            new ThreadPoolExecutor.AbortPolicy());
    Callable c1 = () -> {
        System.out.println("callable one...");
        Thread.sleep(100);
        System.out.println("callable one one...");
        System.out.println(1 / 0);
        return "callable success one";
    };
    Callable c2 = () -> {
        System.out.println("callable two...");
        Thread.sleep(1000);
        System.out.println("callable two two...");
        System.out.println(1 / 0);
        return "callable success two";
    };
    Callable c3 = () -> {
        System.out.println("callable three...");
        Thread.sleep(5000);
        System.out.println("callable three three...");
        // System.out.println(1 / 0);
        return "callable success three";
    };
    List> callableList = new ArrayList<>();
    callableList.add(c1);
    callableList.add(c3);
    callableList.add(c2);
    // invokeAny()方法是阻塞方法, 只需要等待任意一个任务执行完成并返回任务结果, 并且会取消其他任务的执行;
    // invokeAny()方法的返回值是Callable接口的call()方法返回值;
    // invokeAny()方法执行的任务列表中的某一个任务抛出异常, 就会抛弃当前任务并执行下一个任务;
    // invokeAny()方法执行的任务列表中的所有任务都抛出异常, 那么调用当前线程池任务的线程(譬如主线程)也会抛出异常;
    try {
        String result = threadPoolExecutor.invokeAny(callableList);
        System.out.println("result is: " + result);
    } finally {
        threadPoolExecutor.shutdown();
    }
    System.out.println("主线程方法什么时候执行... ...");
    // callable one...
    // callable two...
    // callable three...
    // callable one one...
    // callable two two...
    // callable three three...
    // result is: callable success three
    // 主线程方法什么时候执行... ...
}

六 线程池的关闭命令

public void shutdown():关闭线程池,不允许再提交新任务,但是会处理完全已提交的任务,线程池的状态由RUNNING(运行状态)转换为SHUTDOWN状态;
public List shutdownNow():立即关闭线程池,不允许再提交新任务,而且也不会处理阻塞队列中的任务,线程池的状态由RUNNING(运行状态)转换为STOP状态;
public boolean isShutdown():判断线程池是否调用过shutdown()关闭命令;
public boolean isTerminating():判断线程池是否正在关闭;
public boolean isTerminated():判断线程池是否已经关闭;

static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60,
        TimeUnit.SECONDS,
        new ArrayBlockingQueue<>(1),
        new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) throws InterruptedException {
    Callable c1 = () -> {
        System.out.println("callable one...");
        return "callable success one";
    };
    try {
        threadPoolExecutor.submit(c1);
        // 还没关闭线程池资源
        testMsg("未关闭线程池");
    } finally {
        threadPoolExecutor.shutdown();
        // 已经关闭线程池资源
        testMsg("执行关闭线程池命令");
    }
    // 等待线程池资源关闭完全
    Thread.sleep(2000);
    testMsg("完全关闭线程池");
    // 未关闭线程池 threadPoolExecutor.isShutdown() is: false
    // callable one...
    // 未关闭线程池 threadPoolExecutor.isTerminating() is false
    // 未关闭线程池 threadPoolExecutor.isTerminated() is false
    // 执行关闭线程池命令 threadPoolExecutor.isShutdown() is: true
    // 执行关闭线程池命令 threadPoolExecutor.isTerminating() is true
    // 执行关闭线程池命令 threadPoolExecutor.isTerminated() is true
    // 完全关闭线程池 threadPoolExecutor.isShutdown() is: true
    // 完全关闭线程池 threadPoolExecutor.isTerminating() is false
    // 完全关闭线程池 threadPoolExecutor.isTerminated() is true
}
public static void testMsg(String name) {
    System.out.println(name + " threadPoolExecutor.isShutdown() is: "
            + threadPoolExecutor.isShutdown());
    System.out.println(name + " threadPoolExecutor.isTerminating() is "
            + threadPoolExecutor.isTerminating());
    System.out.println(name + " threadPoolExecutor.isTerminated() is "
            + threadPoolExecutor.isTerminated());
}

你可能感兴趣的:(java,开发语言,后端)