请教下线程池提交线程池的写法

2022-11-29 15:22:45 +08:00
 rqxiao
    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(){})

2113 次点击
所在节点    Java
17 条回复
shazi199
2022-11-29 15:29:19 +08:00
应该可以设置拒绝策略吧,没必要再去判断了
assiadamo
2022-11-29 15:31:42 +08:00
ipwx
2022-11-29 15:33:00 +08:00
难道 canCreateThreads <= 0 就把任务扔了么。。。流控也不应该依赖 threadPool 的具体实现来做吧,这思路清奇。
urzz
2022-11-29 15:35:15 +08:00
用这个判断的话,那还需要 workQueue 干嘛。。。
出于啥考虑要用这个方式啊,这个思路着实看不懂
rqxiao
2022-11-29 15:41:37 +08:00
额 。还有补充一点#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());
}
}
```
rqxiao
2022-11-29 15:43:10 +08:00
@rqxiao 这个代码也不是很明白
chendy
2022-11-29 15:44:11 +08:00
@rqxiao 看麻了,直接结束不就完事了么……
rqxiao
2022-11-29 15:45:48 +08:00
@urzz
目前是这样的代码。但使用起来还没发生过
else{
logger.error(" 已达到本应用处理上限,请稍后再试");
//TODO 发送消息通知
}
loveaeen
2022-11-29 16:27:40 +08:00
使用线程池的优势就是其本身可以维护内部线程的中断与创建,不需要我们来管这东西。想拒绝线程可以设置 BlockQueue 和 rejectPolicy 来解决。
如果你们非要想自己创建指定数量线程并且想在线程内随意中止,那么不如采用 AtomicInteger 之类的全手动增删。
建议多看看 2 楼文档
urzz
2022-11-29 16:37:49 +08:00
@rqxiao 那还真是用线程池来实现流控啊,惊了个呆

手动 interrupt 是没有什么意义的,因为线程池本身会去做这些事。。建议看看 2 楼的文档+1
rqxiao
2022-11-29 16:40:06 +08:00
总体的代码 ![ ]( https://imgur.com/a/oSc4eVD)
wetalk
2022-11-29 16:41:50 +08:00
你的写法极少见,其次,getActiveCount()方法的注释有个单词,approximate ,近似的。

[Returns the approximate number of threads that are actively executing tasks.]
rqxiao
2022-11-29 16:43:47 +08:00
Jooooooooo
2022-11-29 16:44:07 +08:00
直接提交即可

你应该把拒绝策略放到线程池里做, 线程池不就干这个的吗?
X0ray
2022-11-29 16:50:18 +08:00
你这样还不如在外层加一个 Semaphore ,通过信号量的数量来控制提交和写日志
theniupa
2022-11-29 17:41:46 +08:00
你还不如用一个 ArrayBlockingQueue 指定一个长度,在 RejectPolicy 里面拿到这个 work-queue,在满任务 put 阻塞一下..
clickhouse
2022-11-29 18:51:01 +08:00
workQueue 已经设置队列了,new ThreadPoolExecutor.CallerRunsPolicy() 也已经设置拒绝策略了,用线程池就是希望自动管理,所以你只管提交就可以了。如果你觉得实际与期望不符,那么你应该去修改新建线程池的参数。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/898802

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX