java如何保持一个固定大小的列表库?
我正在读取一个很大的URL文件,并向服务发出请求。请求由返回ListenableFuture
的客户端执行。现在我想保留一个ListenableFuture
池,例如,最大限度地同时执行N
期货
我看到的问题是,由于第三方库,我无法控制ExecutorService
中执行的ListenableFuture
。否则我会创建一个FixedSizePool
并创建我自己的Callable
1)一个幼稚的实现是产生N
期货,然后使用AllAsList
,这将满足固定大小的标准,但让所有人等待最慢的请求。
无序处理是可以的
2)一个稍微好一点的天真选择是使用第一个想法,并将其与速率限制器结合起来,通过设置N
和rate
,使并发请求的数量非常接近所需的池大小。但我实际上并不是在寻找一种限制通话的方法,例如使用RateLimiter
3)最后一个选项是生成N
期货,并有一个生成新期货的回调。这满足了固定大小的标准,并最大限度地减少了空闲时间,但在那里我不知道如何检测我的程序是否结束,即关闭文件
4)一种与ListenableFuture
无关的方法是直接.get()
结果,并通过创建一个简单的Threadpool
来处理尴尬的并行任务
为了知道作业队列是空的,即关闭文件,我考虑使用CountdownLatch
。这应该适用于许多选项
# 1 楼答案
嗯,你觉得只用
java.util.concurrent.Semaphore
怎么样您可以通过使用
Futures.addCallback(ListenableFuture, FutureCallback)
来添加其他侦听器来处理结果,只要您小心地release()
处理成功和错误这可能有用
# 2 楼答案
你的选择3听起来很合理。如果您想清楚地检测所有请求何时完成,一种简单的方法是创建一个新的
SettableFuture
来表示完成当您的回调尝试从队列中获取下一个请求,并发现它为空时,您可以在将来调用
set()
,通知正在等待所有请求完成的任何内容。传播来自单个请求的异常留给读者作为练习# 3 楼答案
使用
FixedSizePool
来完成尴尬的并行任务,并立即.get()
预测未来的结果这简化了代码,并允许每个工作人员拥有可修改的上下文