Java并发24 再来一个例子来看看线程池执行过程

本文通过一个实例详细解析Java线程池的工作过程,包括核心线程执行任务、任务入队、饱和策略的触发以及AbortPolicy等四种饱和策略的解释。建议读者亲自尝试各种策略以理解其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程池执行过程

一 直接上例子
public class ThreadPoolExecutorTest {

    private static ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS, new
            ArrayBlockingQueue<>(10), new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) throws InterruptedException {
        for (int i = 1; i <= 14; i++) {
            Callable<Boolean> task = createTask(i);
            pool.submit(task);
            System.out.println("after task:" + i + " submitted, current active count: "
                    + pool.getActiveCount() + ", size of queue: " + pool.getQueue().size());
        }
        System.out.println("size of queue: " + pool.getQueue().size());
        for (;;){
            TimeUnit.SECONDS.sleep(11);
            System.out.println("size of queue: " + pool.getQueue().size());
            if (0 == pool.getQueue().size())
                break;
        }
        pool.shutdown();
    }

    /**
     * @Author Xu hao
     * @Description 创建任务
     * @Date 2019/3/19 0:08
     * @param i
     * @return java.util.concurrent.Callable<java.lang.Boolean>
     **/
    private static Callable<Boolean> createTask(int i){

        Callable<Boolean> callable = () -> {
            TimeUnit.SECONDS.sleep(10);
            System.out.println("thread: " + Thread.currentThread().getName() + " execute task: " + i);
            return true;
        };

        return callable;
    }
}

我们在上一篇文章的例子基础上每隔11秒打印一下工作队列的size,
运行结果如下:

after task:1 submitted, current active count: 1, size of queue: 0
after task:2 submitted, current active count: 2, size of queue: 0
after task:3 submitted, current active count: 2, size of queue: 1
after task:4 submitted, current active count: 2, size of queue: 2
after task:5 submitted, current active count: 2, size of queue: 3
after task:6 submitted, current active count: 2, size of queue: 4
after task:7 submitted, current active count: 2, size of queue: 5
after task:8 submitted, current active count: 2, size of queue: 6
after task:9 submitted, current active count: 2, size of queue: 7
after task:10 submitted, current active count: 2, size of queue: 8
after task:11 submitted, current active count: 2, size of queue: 9
after task:12 submitted, current active count: 2, size of queue: 10
after task:13 submitted, current active count: 3, size of queue: 10
after task:14 submitted, current active count: 4, size of queue: 10
size of queue: 10
thread: pool-1-thread-1 execute task: 1
thread: pool-1-thread-2 execute task: 2
thread: pool-1-thread-4 execute task: 14
thread: pool-1-thread-3 execute task: 13
size of queue: 6
thread: pool-1-thread-1 execute task: 3
thread: pool-1-thread-2 execute task: 4
thread: pool-1-thread-3 execute task: 6
thread: pool-1-thread-4 execute task: 5
size of queue: 2
thread: pool-1-thread-1 execute task: 7
thread: pool-1-thread-2 execute task: 8
thread: pool-1-thread-3 execute task: 9
thread: pool-1-thread-4 execute task: 10
size of queue: 0
thread: pool-1-thread-1 execute task: 11
thread: pool-1-thread-2 execute task: 12

结合上面的运行日志,来看看线程池执行的过程,
->日志前两行:线程池有两个核心线程,去执行两个任务,工作队列空闲
->日志3~12行:线程池核心线程已满,再来任务放入工作队列中
->日志13~14行:此时线程池核心线程已满,工作队列已满(放了10个任务),再来两个任务创建两个线程。(此时线程池有四个线程)
->接下来任务1 2 13 14被线程1 2 3 4执行完成
->线程池从工作队列拿出任务3 4 5 6 再去让线程1 2 3 4执行 工作队列还剩下6个任务
->线程池从工作队列拿出任务7 8 9 10 再去让线程1 2 3 4执行 工作队列还剩下2个任务
->线程池从工作队列拿出任务11 12 再去让线程1 2 执行 工作队列还剩下0个任务
->所有任务执行完成,线程池关闭

二 饱和策略

这里注意:我刚刚好提交了14个任务,如果再来一个任务,线程池已经饱和了,就会使用饱和策略来处理提交的任务,饱和策略这里我用了AbortPolicy,线程池会直接抛出异常如下

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@ca494b rejected from java.util.concurrent.ThreadPoolExecutor@1a4f24f[Running, pool size = 4, active threads = 4, queued tasks = 10, completed tasks = 0]

几种饱和策略:

  1. AbortPolicy:直接抛出异常
  2. CallerRunsPolicy:只用调用者所在线程来运行任务
  3. DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务
  4. DiscardPolicy:不处理,不丢弃

读者可以每一种都去写个Demo试试看,具体使用哪种饱和策略,要结合具体的生产需求。后面我们讲线程池的合理使用会讲到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值