我有一个Java服务器应用程序,它监视大量的Gmail IMAP文件夹以获取新消息。
它是用javamail IdleManager实现的。我有一个像这样工作的计划任务(缩短的例子)
经过多次运行后,我遇到了一种僵局。 同步的folder.close(false)永远挂起。
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
props.put("mail.event.scope", "session"); // or "application"
props.put("mail.event.executor", es);
props.setProperty("mail.imaps.usesocketchannels", "true");
// initialized in other place.
// ArrayList<IMAPFolder> folders = new ArrayList<>();
for (IMAPFolder folder : folders) {
folder.close(false);
}
folders = new ArrayList<>();
// initialized in other place.
// ArrayList<Store> stores = new ArrayList<>();
for (Store store : stores) {
store.close();
}
stores = new ArrayList<>();
// initialized in other place.
// ExecutorService es = Executors.newCachedThreadPool();
//IdleManager idleManager = new IdleManager(session, es);
es = Executors.newCachedThreadPool();
if (idleManager != null) {
idleManager.stop();
}
idleManager = new IdleManager(session, es);
//here I run a number of threads in a loop.
以下是这些主题的简化示例。
Store store = connectStore();
IMAPFolder folder = (IMAPFolder) store.getFolder("INBOX");
stores.add(store);
folders.add(folder);
folder.open(Folder.READ_ONLY);
idleManager.watch(folder);
我确定这是连接到IdleManager,因为我已经尝试了没有idleManager.watch(文件夹)的代码,一切正常。
顺便说一下,我已经尝试this approach检测Java中的死锁,但没有显示任何死锁。
如果我从代码中删除关闭文件夹块并仅关闭存储 - 相同的方案。 store.close()就像folder.close(false)一样永远挂起。
我感谢任何帮助!谢谢!