【发布时间】:2013-04-06 11:58:22
【问题描述】:
我在 Android 的 asmack 库中遇到了一个奇怪的问题。该库使用 ExecutorService 来解析传入的数据包:
private ExecutorService listenerExecutor;
listenerExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable,
"Smack Listener Processor (" + connection.connectionCounterValue + ")");
thread.setDaemon(true);
return thread;
}
});
(...)
listenerExecutor.submit(new ListenerNotification(packet));
(...)
/**
* A runnable to notify all listeners of a packet.
*/
private class ListenerNotification implements Runnable {
private Packet packet;
public ListenerNotification(Packet packet) {
this.packet = packet;
}
public void run() {
for (ListenerWrapper listenerWrapper : connection.recvListeners.values()) {
listenerWrapper.notifyListener(packet);
}
}
}
一切正常,直到调用 submit() 方法时,也调用了 ListenerNotification 的构造函数,但不再调用 ListenerNotification 中的 run() 方法。
这可能是什么原因? ExecutorService 中是否有一些机制可能导致对提交的调用被忽略?
【问题讨论】:
-
ListenerNotification.run()是否运行一次?您是否尝试过使用默认的 ThreadFactory 而不是您自己的? -
是的,它会运行一段时间然后停止。这不是确定性的,也不是可重现的,这让我想知道......我没有对这个库代码进行更改 - 我只在我的两个项目中使用它。我以前使用过同一个库,我没有遇到这种性质的问题,现在它们出现了。我什至从 run() 方法中迭代的侦听器列表中删除了我自己的侦听器,因为我认为可能我正在做的任何事情都花费了太长时间,但这也没有帮助。
-
尝试旧版本的库,看看它现在是否也发生了。也许单线程执行器处于某种“锁定”状态。这是我听说的关于 aSmack 此类行为的第一份报告。
-
是的,线程实际上被我自己的代码阻塞了。
标签: android executorservice java.util.concurrent asmack