private static ThreadPoolExecutor getThreadPoolExecutor() { int corePoolSize=10; int maximumPoolSize=10; long keepAliveTime=1000L; BlockingQueue<Runnable> workQueue=new LinkedBlockingDeque<>(100); ThreadPoolExecutor threadPoolExecuor = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, workQueue, new ThreadPoolExecutor.CallerRunsPolicy() ); return threadPoolExecutor; }
如下种写法常用吗,判断 ActiveCount 来提交线程
#1 int canCreateThreads = threadPool.getCorePoolSize()- threadPool.getActiveCount(); log.info(" 支持核心线程数 : {} 个, 已激活 {} 个线程, 还可创建线程数 : {} 个", threadPool.getCorePoolSize(), threadPool.getActiveCount(),canCreateThreads); if (canCreateThreads > 0) { executor .execute(new Runnable(){}) }
之前工作中一直使用这种简单的方式,有任务时,直接提交线程池,具体怎么执行根据线程池配置来。
#2 executor.execute(new Runnable(){})
1 shazi199 2022-11-29 15:29:19 +08:00 应该可以设置拒绝策略吧,没必要再去判断了 |
2 assiadamo 2022-11-29 15:31:42 +08:00 ![]() |
![]() | 3 ipwx 2022-11-29 15:33:00 +08:00 ![]() 难道 canCreateThreads <= 0 就把任务扔了么。。。流控也不应该依赖 threadPool 的具体实现来做吧,这思路清奇。 |
![]() | 4 JadeLove 2022-11-29 15:35:15 +08:00 用这个判断的话,那还需要 workQueue 干嘛。。。 出于啥考虑要用这个方式啊,这个思路着实看不懂 |
![]() | 5 rqxiao OP 额 。还有补充一点#1 里 runnable 的 run 方法 最后还会有一段这样的代码,每次执行完一个线程的逻辑之后,还给他 interrupt()一下,然后自抛自捕。 ``` finally { logger.debug("{} 队列消费,标志线程为中断", Thread.currentThread().getName()); Thread.currentThread().interrupt(); throw new InterruptedException( Thread.currentThread().getName() + ".run() interrupted : 执行完毕"); } } catch (InterruptedException e) { if (e.getMessage().endsWith(SysConstants.FINISH_INTERRUPTED)) { logger.debug(e.getMessage()); } else { logger.error(e.getMessage()); } } ``` |
![]() | 8 rqxiao OP |
9 loveaeen 2022-11-29 16:27:40 +08:00 使用线程池的优势就是其本身可以维护内部线程的中断与创建,不需要我们来管这东西。想拒绝线程可以设置 BlockQueue 和 rejectPolicy 来解决。 如果你们非要想自己创建指定数量线程并且想在线程内随意中止,那么不如采用 AtomicInteger 之类的全手动增删。 建议多看看 2 楼文档 |
![]() | 10 JadeLove 2022-11-29 16:37:49 +08:00 |
![]() | 11 rqxiao OP 总体的代码  |
![]() | 12 wetalk 2022-11-29 16:41:50 +08:00 你的写法极少见,其次,getActiveCount()方法的注释有个单词,approximate ,近似的。 [Returns the approximate number of threads that are actively executing tasks.] |
![]() | 13 rqxiao OP []( https://imgse.com/i/zdcgj1) |
14 Jooooooooo 2022-11-29 16:44:07 +08:00 直接提交即可 你应该把拒绝策略放到线程池里做, 线程池不就干这个的吗? |
15 X0ray 2022-11-29 16:50:18 +08:00 你这样还不如在外层加一个 Semaphore ,通过信号量的数量来控制提交和写日志 |
16 theniupa 2022-11-29 17:41:46 +08:00 ![]() 你还不如用一个 ArrayBlockingQueue 指定一个长度,在 RejectPolicy 里面拿到这个 work-queue,在满任务 put 阻塞一下.. |
17 clickhouse 2022-11-29 18:51:01 +08:00 workQueue 已经设置队列了,new ThreadPoolExecutor.CallerRunsPolicy() 也已经设置拒绝策略了,用线程池就是希望自动管理,所以你只管提交就可以了。如果你觉得实际与期望不符,那么你应该去修改新建线程池的参数。 |