求教一个 Java 线程池的问题

2022-09-02 09:56:59 +08:00
 abc0123xyz

ThreadPoolExecutor 创建线程池
Callable 接口的实现类处理逻辑

在实现类的 call()中,每次都要访问一个资源,这一步要耗时很久。持有这个资源的对象其实是可以复用的,怎么样才可以让线程本身持有这个资源?或者各位大佬给点其他思路

3182 次点击
所在节点    Java
25 条回复
nothingistrue
2022-09-02 15:57:35 +08:00
@abc0123xyz 你要多个线程对同一个对象互斥,又要这个对象依赖的第三方对象能被多个线程复用。这是要一个并发场景下的共享对象,一部分状态是隔离的,另一部分状态是公用的,这是不可能的。

狗日的,我看你的描述头疼的很。

首先,你到底有没有这样的数据或者业务要求:最多一个线程处理它,如果是多个线程同时处理的时候,必须排队。如果没有的话,就别提在关注这一点。我看你的业务场景压根不涉及并发加锁。
nothingistrue
2022-09-02 16:12:57 +08:00
提醒你一点:你提交给执 Executors 的是一个实现 Callable 接口的对象,不是 Callable 类的对象,这个对象不只有 call() 方法,是可以定义其他字段的。

所以你没必要在 call() 方法中去生成或申请那个资源,你可以在你实现 Callable 的类(别再用匿名类了)上定义一个字段来映射那个资源,然后在提交到 Executors 前就给它设值。这个设值过程,就跟线程池或异步执行器无关了,就是典型的单例模式。

上面不会解决你想要的超时处理。
nothingistrue
2022-09-02 16:24:00 +08:00
超时那个问题,把 future.get() ,换成:
try {
future.get(long timeout, TimeUnit unit);
} catch (TimeoutException e){
// 超时时候的处理,这里你想咋处理就咋处理,但是当前这个任务肯定是失败了。
}
corningsun
2022-09-02 17:00:32 +08:00
@abc0123xyz 重点描述下你的第三方工具到底是啥吧?什么协议,支持多少并发? QPS 之类的有限制吗?

卡死的原因要找出来。

然后再根据 kafka 数据量有多少,决定单线程跑,还是起多线程,要不要加限速
chenshun00
2022-09-02 18:47:24 +08:00
为啥第三方卡死了,你就把对象丢了呢,在这里做个熔断就好了吧,不就可以保持这个一直可用了么。

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

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

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

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

© 2021 V2EX