线程池的使用--Executor

1:自定义线程池注意的点:1:核心线程数:获取当前服务的可用核数。2:一定要声明有界队列。

个人倾向callable而不是runnable, 便于观察线程池的返回值。futrueTask提供一次性添加所有任务,最后一次性提交,支持返回值。

2:是否需要手动调用shutdown:

       shutdown会按过去执行已提交任务的顺序发起一个有序的关闭,但是不接受新任务。如果已经关闭,则调用没有其他作用。当Executor已经关闭,并且Executor将有限边界用于最大线程和工作队列容量,且已经饱和时,在方法execute()中提交的新任务将被拒绝。shutdown只是将空闲的线程interrupt()了,因此在shutdown()之前提交的任务可以继续执行直到结束。 如果不shutdown() 池中的线程执行完了之后自然就被销毁了,就跟你不用Executor而自己new一个Thread然后run一样,后续这个线程会自己关闭。

(一):队列满了,捕获异常后,改为同步执行。

package com.tongbanjie.fee.job;

import org.springframework.core.task.TaskRejectedException;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Author: leBang
 * @Date: 18/8/31 11:50
 * @Description: * 线程池的使用-提交任务及获取结果
 */

public class ThreadPoolAction {
    private static int totalTask = 100;

    private static ThreadPoolAction instance;

    private static ThreadPoolAction getInstance() {
        if (null == instance) {
            instance = new ThreadPoolAction();
        }
        return instance;
    }

    /**
     * 异步线程池
     */
    private CompletionService<Integer> completionService = new ExecutorCompletionService<>(new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), 20, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024)));
    /***
     * 普通线程池
     */
    private ExecutorService executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), 20, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024));

    public static void main(String[] args) {
        ThreadPoolAction.getInstance().completeServiceThreadPool();
        ThreadPoolAction.getInstance().executorServiceThreadPool();
    }

    /**
     * 相当于executorService + BlockingDeque,方便了获取结果
     */
    public void completeServiceThreadPool() {
        Long startTime = System.currentTimeMillis();
        for (int i = 0; i < totalTask; i++) {
            LeBangTask task = new LeBangTask();
            try {
                completionService.submit(task);
            } catch (TaskRejectedException e) {
                try {
                    //队列已满,改为同步执行
                    task.call();
                } catch (Exception e1) {
                    System.out.println("任务同步执行失败!");
                }
            }
        }

        for (int i = 0; i < totalTask; i++) {
            try {
                System.out.println("线程ID:" + completionService.take().get() + "已经执行完毕!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }

        Long endTime = System.currentTimeMillis();
        System.out.println("==任务执行完毕! 总耗时: " + (endTime - startTime) + " ms ==");
    }

    /**
     * 新建线程池
     */
    public void executorServiceThreadPool() {
        Long startTime = System.currentTimeMillis();
        List<Future<Long>> futureList = new ArrayList<>();
        for (int i = 0; i < totalTask; i++) {
            LeBangTask task = new LeBangTask();
            try {
                Future<Long> future = executorService.submit(task);
                futureList.add(future);
            } catch (TaskRejectedException e) {
                try {
                    //队列已满,改为同步执行
                    task.call();
                } catch (Exception e1) {
                    System.out.println("任务同步执行失败!");
                }
            }
        }

        for (Future<Long> future : futureList) {
            try {
                System.out.println("线程ID:" + future.get() + "已经执行完毕!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        Long endTime = System.currentTimeMillis();
        System.out.println("==任务执行完毕! 总耗时: " + (endTime - startTime) + " ms ==");
    }

    class LeBangTask implements Callable {
        @Override
        public Long call() throws Exception {
            //=======  业务逻辑开始  =======
            System.out.println("线程ID: " + Thread.currentThread().getId() + "加入执行!");
            //=======  业务逻辑结束  =======
            return Thread.currentThread().getId();
        }
    }
}

(二)提供拒绝策略,队列满了阻塞、直到队列有新的空间再插入。

package com.tongbanjie.fee.job;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Author: leBang
 * @Date: 18/10/24 20:08
 * @Description: *
 */

public class ThreadPoolAction {
    private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolAction.class);
    private static int totalTask = 100;
    private static ThreadPoolAction instance;
    
    private static ExecutorService executorService;

    private static ThreadPoolAction getInstance() {
        if (null == instance) {
            instance = new ThreadPoolAction();
        }
        return instance;
    }

    static {
        RejectedExecutionHandler handler = new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                try {
                    executor.getQueue().put(r);
                    LOGGER.info("队列已满,阻塞直到有空间再插入!");
                } catch (InterruptedException e) {
                    LOGGER.error("执行器InterruptedException,插入队列失败!");
                }
            }
        };

        executorService = new ThreadPoolExecutor(15, 20, 3,
                TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(500), handler);
    }


    public static void main(String[] args) {
        ThreadPoolAction.getInstance().executorServiceThreadPool();
    }

    /**
     * 新建线程池
     */
    public void executorServiceThreadPool() {
        Long startTime = System.currentTimeMillis();
        List<Future<Long>> futureList = new ArrayList<>();
        for (int i = 0; i < totalTask; i++) {
            LeBangTask task = new LeBangTask();
            Future<Long> future = executorService.submit(task);
            futureList.add(future);
        }

        for (Future<Long> future : futureList) {
            try {
                System.out.println("线程ID:" + future.get() + "已经执行完毕!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        Long endTime = System.currentTimeMillis();
        System.out.println("==任务执行完毕! 总耗时: " + (endTime - startTime) + " ms ==");
    }

    class LeBangTask implements Callable {
        @Override
        public Long call() throws Exception {
            //=======  业务逻辑开始  =======
            System.out.println("线程ID: " + Thread.currentThread().getId() + "加入执行!");
            //=======  业务逻辑结束  =======
            return Thread.currentThread().getId();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/watson1360884839/article/details/82258182