private static ThreadPoolExecutor getThreadPoolExecutor() {
int corePoolSize=10;
int maximumPoolSize=10;
long keepAliveTime=1000L;
BlockingQueue<Runnable> workQueue=new LinkedBlockingDeque<>(100);
ThreadPoolExecutor threadPoolExecutor = 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 1
|
3
ipwx 2022-11-29 15:33:00 +08:00 1
难道 canCreateThreads <= 0 就把任务扔了么。。。流控也不应该依赖 threadPool 的具体实现来做吧,这思路清奇。
|
4
urzz 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
urzz 2022-11-29 16:37:49 +08:00
|
11
rqxiao OP 总体的代码 ![ ]( https://imgur.com/a/oSc4eVD)
|
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 [![zdcgj1.jpg]( https://s1.ax1x.com/2022/11/29/zdcgj1.jpg)]( 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 1
你还不如用一个 ArrayBlockingQueue 指定一个长度,在 RejectPolicy 里面拿到这个 work-queue,在满任务 put 阻塞一下..
|
17
clickhouse 2022-11-29 18:51:01 +08:00
workQueue 已经设置队列了,new ThreadPoolExecutor.CallerRunsPolicy() 也已经设置拒绝策略了,用线程池就是希望自动管理,所以你只管提交就可以了。如果你觉得实际与期望不符,那么你应该去修改新建线程池的参数。
|