我试图将一个监听器变成一个Future,用于异步连接.我不习惯使用java期货,我有一些javascript承诺的经验,但我没有看到如何在java中编写它(我在Java 8中看到"CompletableFuture"可以解决我的问题,不幸的是我是坚持使用java 7).这是我到目前为止所做的:
public Future<Boolean> checkEmailClientConfiguration(final EmailClientConfiguration config) {
final Future<Boolean> future = ???;
// In some other languages I would create a deferred
Transport transport = null;
try {
transport = session.getTransport("smtp");
transport.addConnectionListener(new ConnectionListener() {
@Override
public void opened(ConnectionEvent connectionEvent) {
System.out.println("!!!opened!!! ; connected=" + ((SMTPTransport) connectionEvent.getSource()).isConnected());
// HERE I would like to make my future "resolved"
}
@Override
public void disconnected(ConnectionEvent connectionEvent) {
}
@Override
public void closed(ConnectionEvent connectionEvent) {
}
});
transport.connect(config.getMailSMTPHost(),
config.getMailSMTPPort(),
config.getMailUsername(),
config.getMailPassword());
return future;
} catch (final MessagingException e) {
throw e;
} finally{
if(transport != null){
transport.close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我找不到任何简单的方法来做到这一点.到目前为止,我发现的唯一解决方案是扩展FutureTask并在Callable运行结束时等待/休眠,直到某个状态变量设置为已解决.我真的不喜欢在我的业务代码中等待/休眠的想法,可能有一些已经存在的东西让它延期了?(在java中,还是像Apache commons或guava这样的流行库?)
我终于得到了同事的回答.我正在寻找的是Guava:SettableFuture.这是代码的样子:
final SettableFuture<Boolean> future = SettableFuture.create();
Transport transport = null;
try {
transport = session.getTransport("smtp");
transport.addConnectionListener(new ConnectionListener() {
@Override
public void opened(ConnectionEvent connectionEvent) {
future.set(((SMTPTransport) connectionEvent.getSource()).isConnected());
}
@Override
public void disconnected(ConnectionEvent connectionEvent) {
}
@Override
public void closed(ConnectionEvent connectionEvent) {
}
});
transport.connect(config.getMailSMTPHost(),
config.getMailSMTPPort(),
config.getMailUsername(),
config.getMailPassword());
} catch (final MessagingException e) {
future.setException(e);
} finally{
if(transport != null){
transport.close();
}
}
return future;
Run Code Online (Sandbox Code Playgroud)