如何处理不可中断的阻塞(ExecutorService)

时间:2013-04-22 07:48:58

标签: java executorservice

我想使用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任务(我已使用timeout:30和{{进行了测试1}}在Linux attempts:5文件中,以模拟长时间运行的DNS查询。)

结果是,如果当前正在运行的工作线程无法停止,当我提交另一个DNS任务时,则必须创建第二个线程,对于第三个任务,我将有第三个线程,依此类推。如果DNS服务器没有响应,那么我会在池中有一堆工作线程什么也不做(即等待超时后尝试的负DNS响应*尝试= 150秒)。

我担心如果在线程池中创建了许多线程并且它们处于活动状态(我使用缓存线程池btw),我将不得不处理另一类问题......

我知道可以通过关闭底层套接字来停止不可中断的阻塞套接字读取调用,但事实并非如此。

有谁知道如何处理这类问题?

1 个答案:

答案 0 :(得分:1)

DNS查找调用由系统调用完成。所以,java不能打断它。唯一的方法是创建一个线程池,并希望不好的请求不会经常溢出线程池。或者只是使用适当的超时调整resolv.conf。你无法用Java做什么。

作为替代方案,您可以寻找一个最可能是可中断的纯Java dns客户端实现。例如。快速谷歌搜索显示:http://sourceforge.net/p/dnsjava/