我尝试通过使用ThreadPoolExecutor调用在单独线程中执行DNS查询的所有例程来实现异步DNS解析器。
我对可调用对象的定义如下:
public class SocketAddressCreator extends DnsCallable<String, InetSocketAddress> {
private static final Logger log = Logger.getLogger(SocketAddressCreator.class);
private int port;
public SocketAddressCreator(String host, int port) {
super(host);
this.port = port;
}
public InetSocketAddress call() throws Exception {
log.info("Starting to resolve. Host is: " + target + " .Port is: " + port);
long start = System.currentTimeMillis();
**InetSocketAddress addr = new InetSocketAddress(target, port);**
log.info("Time waiting: " + (System.currentTimeMillis() - start));
return addr;
}
}
基本上,可调用对象将尝试将主机名解析为InetAddress。
然后我定义一个ExecutorService:
executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory()
.newThread(r);
t.setName("DnsResolver");
t.setDaemon(true);
return t;
}
});
我提交了可调用任务:
..............
**Future<V> f = executor.submit(task);**
try {
log.info("Query will be made");
log.info("Queue size: " + executor.getQueue().size());
**result = f.get(timeout, TimeUnit.MILLISECONDS);**
log.info("Queue size: " + executor.getQueue().size());
log.info("Query is finished");
} catch (TimeoutException e) {
boolean isCancelled = f.cancel(true);
log.info("Task was cancelled: " + isCancelled);
log.info("Queue size: " + executor.getQueue().size());
..........
}
..............
然后我看着我的程序抛出的日志,它们很奇怪。这是我在解决DNS中有一个超时:
DnsResolver : Queue size: 1
DnsResolver : Task was cancelled: true
DnsResolver : Queue size: 1
因此,在提交我的可调用对象之后,但在调用future.get(long,TimeUnit)之前,队列大小为1。但对我来说没关系。但是,在捕获TimeoutException并取消Future之后,队列大小是相同的(1)。在我的程序中,只有一个线程将可调用的任务提交给ExecutorService,同一个线程也将检索结果。除此之外,这里还有一个更奇怪的问题:不调用Callable.call()方法,因为如果调用它,我将得到一条日志消息:
log.info("Starting to resolve. Host is: " + target + " .Port is: " + port);
那么,将来如何可能.get(long,TimeUnit)方法在未调用可调用对象时抛出TimeoutException呢?
进行DNS查询的以下调用:1/new InetSocket地址(String, int)-名称查找2/InetAddress.getByName(String)-名称查找3/InetAddress.getHostName()-反向名称查找
非中断阻塞呼叫!
正如我之前所说,我使用由单个线程组成的线程池。我没有意识到有多个线程是必要的
因此,如果我从future.get(long,TimeUnit)调用中捕获了TimeoutException,然后我尝试通过调用future.cancel(boolean)来取消正在进行的任务。。。我不会阻止单个正在运行的线程执行它正在执行的操作。
我试图模拟一个长时间运行的DNS查询,我修改resolv.conf如下:nameserver X. X. X. X//这个地址没有一个有效的DNS服务器!选项超时: 30我希望DNS客户端在返回给我一个否定/肯定的响应之前阻止一段时间。
我已经对我的应用程序进行了负载测试,这简直是一场灾难!这是因为我有一个单独的线程来解析这些DNS查询并调用future.get(long,TimeUnit)不会停止它!
当然,我可以增加线程池的大小。我已经这样做了,它解决了我的问题。但是…在我的池大小中有多个线程来解析这些DNS查询似乎很愚蠢,因为只有一个线程提交应该解析DNS查询的可调用项,而同一个线程也会得到结果。
我在我的android应用程序中使用jackson-core.jar(2.4.2)。我在构建路径中包含了jackson-core.jar(2.4.2)。 当调用新的JsonFactory()时,有一个崩溃:NoClassDefFoundError异常 Logcat输出 12-10 23:45:54.446:E/AndroidRuntime(6287):致命异常:IntentService[File
问题内容: 我有一个带有可观察列表的ComboBox,该列表随用户键入字符或进行选择而更新。当我从ComboBox中选择一个项目并调用我的侦听器事件,然后从ComboBox的ObservableList中调用clear()方法时,引起了我遇到的问题。 完整代码 现在,当我收到错误消息时,ObservableList会按原样出现,但我仍然收到此异常。尝试调试此错误导致我的IDE在调用setAll(运
我希望能够获得我已经提交给执行服务(特别是线程池执行器)的Callable(因此它们不能通过getQueue())。 我试图创建一个子类来覆盖beForeExecute之前的
我正在使用Android应用程序,我想以某种方式打印HashMap的键和值。假设以下是HashMap的内容: 我想以这样一种方式打印HashMap键和值,即字母键首先按字母顺序打印,然后是数字键按升序打印: 我现在做的是: > < li> 获取密钥集并将其保存到数组列表中 使用比较器对数组列表进行排序 使用排序列表打印出地图中的值 这是我的代码: 到目前为止,它还在工作,但是在某些情况下,我没有得
问题内容: 我偶然发现了一个问题,可以总结如下: 当我手动创建线程(即通过实例化)时,将适当地调用它。但是,当我与一起使用时,处理程序将被忽略。我错过了什么? 我期望:消息“未捕获的异常…”的三倍 我得到:消息一次(由手动创建的线程触发)。 在Windows 7和Mac OS X 10.5上用Java 1.6复制。 问题答案: 因为异常不会被捕获。 您的ThreadFactory生成的线程没有直接
我有一个基于spring的java web应用程序,它使用HSQLDB dbms后端在事务中插入大量记录。为了减少为要插入的记录生成主键的往返次数,我想创建一个存储过程,生成主键,在插入之前将其用作标识符。因此,我用以下代码创建了一个存储过程: 有一个序列GENERATE_PKS_SEQ,用于为要插入的记录生成唯一标识符。此存储过程需要一个数字输入(NUMBEROFIDS)来定义要生成的密钥数。