【JAVA 多线程】线程池 ThreadPoolExecutor使用详解

创建线程池对象 :

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(核心线程数量,最大线程数量,空闲线程最大存活时间,时间单位,任务队列,创建线程工厂,任务的拒绝策略);

线程池处理流程

  1. 线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作 线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下个流程。

  2. 线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这 个工作队列里。如果工作队列满了,则进入下个流程。

  3. 线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程 来执行任务。如果已经满了,则交给饱和策略来处理这个任务 

提交方法

可以使用两个方法向线程池提交任务,分别为execute()和submit()方法。
​
 submit()方法用于提交需要返回值的任务。线程池会返回一个future类型的对象,通过这个 future对象可以判断任务是否执行成功,并且可以通过future的get()方法来获取返回值,get()方 法会阻塞当前线程直到任务完成,而使用get(long timeout,TimeUnit unit)方法则会阻塞当前线 程一段时间后立即返回,这时候有可能任务没有执行完。

execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。

线程池-参数详解

任务队列:

ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO(先进先出)原 则对元素进行排序。

LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO排序元素,吞吐量通 常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。

SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用 移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于Linked-BlockingQueue,静态工 厂方法Executors.newCachedThreadPool使用了这个队列。

PriorityBlockingQueue:一个具有优先级的无限阻塞队列

线程池-任务拒绝策略

 ThreadPoolExecutor.AbortPolicy:             丢弃任务并抛出RejectedExecutionException异常。是默认的策略。
ThreadPoolExecutor.DiscardPolicy:            丢弃任务,但是不抛出异常 这是不推荐的做法。
ThreadPoolExecutor.DiscardOldestPolicy:    抛弃队列中等待最久的任务 然后把当前任务加入队列中。
ThreadPoolExecutor.CallerRunsPolicy:        调用任务的run()方法绕过线程池直接执行。

明确线程池最多可执行的任务数 = 队列容量 + 最大线程数  

 

 代码示例:

        // 创建一个ArrayList来存放异步计算结果
        final List<GzltjRespVO> gzltjRespVOS = Collections.synchronizedList(new ArrayList<>());
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                10, // 核心线程数
                20, // 最大线程数
                10,  // 线程空闲超时时间(单位:秒)
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(20), // 工作队列大小
                new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
        );
        // 提交任务到线程池
        userRoleIdListByRoleIds.forEach(roleId -> {
            threadPoolExecutor.submit(() -> {
                log.info(Thread.currentThread().getName() + "---" + roleId);
                GzltjRespVO gzltjRespVO = calculateGzltjRespVO(roleId, kssj, jzsj);
                synchronized (gzltjRespVOS) {
                    gzltjRespVOS.add(gzltjRespVO);
                }
            });
        });

// 等待所有任务完成
        threadPoolExecutor.shutdown();
        try {
            threadPoolExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Interrupted while waiting for task completion", e);
        }
        gzltjRespVOS.sort(Comparator.comparing(GzltjRespVO::getName).reversed());
        return success(gzltjRespVOS);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海海向前冲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值