我想使用 ExecutorService 框架解决一些 DNS 任务。我使用 java API 进行 DNS 查询: 1/ java.net.InetSocketAddress.InetSocketAddress(String, int) - 名称查找 2/ java.net.InetAddress.getByName(String) - 名称查找 3/ java.net.InetAddress.getHostName () - 反向名称查找
一个典型的 DNS 任务将是一个 Callable 对象,定义如下:
public class IpAddressResolver extends DnsCallable<String, InetAddress> {
public IpAddressResolver(String host) {
super(host);
}
public InetAddress call() throws Exception {
return InetAddress.getByName(target);
}
}
如您所见,这 3 个调用都是不可中断的。问题是,如果Future.get(long, TimeUnit)
超时然后我打电话Future.cancel(boolean)
,我没有任何机会阻止工作线程尝试解析 DNS 任务(我已经 在 Linux文件中进行了测试timeout:30
,以模拟长时间运行的 DNS 查询)。attempts:5
resolv.conf
这样做的结果是,如果当前正在运行的工作线程无法停止,当我提交另一个 DNS 任务时,则必须创建第二个线程,对于第三个任务,我将有第三个线程,依此类推。如果 DNS 服务器没有响应,那么我将在池中有一堆工作线程什么都不做(即等待超时 * 尝试 = 150 秒后出现的否定 DNS 响应)。
恐怕如果创建了许多线程并且在线程池中处于活动状态(我使用缓存线程池顺便说一句),我将不得不处理另一种问题......
我知道可以通过关闭底层套接字来停止不可中断的阻塞套接字读取调用,但我这边并非如此。
有谁知道如何处理这些问题?