我需要的是返回token
对象作为adapter.authenticate()
操作置于线程中的结果。不知道如何从那里返回一个物体,请指教。谢谢。
public Token authenticate(final String email, final String password) {
Thread mThread = new Thread(new Runnable() {
@Override
public void run() {
try {
token = adapter.authenticate(email, password); // I need token to return with authenticate() method.
} catch (NotAuthenticatedException e) {
}
}
});
mThread.start();
}
答案 0 :(得分:5)
实施Callable界面。像运行一样对待调用方法,您可以返回令牌。
答案 1 :(得分:5)
试试这个:
public Token authenticate(final String email, final String password) {
final Token[] tokens = new Token[1];
Thread mThread = new Thread(new Runnable() {
@Override
public void run() {
try {
tokens[0] = adapter.authenticate(email, password);
} catch (NotAuthenticatedException e) {
}
}
});
mThread.start();
mThread.join();
return tokens[0];
}
说明:
token
成为Token
,因为它必须是final
。join
线程,否则authenticate
可能会在线程在tokens[0]
中设置令牌之前返回。还应该注意到,通过这种方式使用线程,你没有取得多少成就。你正在做的事情只是一种昂贵的方式来调用adapter.authenticate(email, password)
。
如果您的目标是在等待身份验证时避免阻止UI,则解决方案需要更复杂。基本上,您需要更改您的应用程序,以便需要进行身份验证的视图元素从禁用开始(例如,它们是灰色的/忽略点击/无论如何)。您执行身份验证是一个单独的线程,如上所述,当它完成时,您可以将事件发送到UI线程。接收到该事件后,UI线程应该启用禁用的视图元素。
答案 2 :(得分:1)
为什么要在另一个线程中启动某些内容然后等待结果呢?只需直接致电adapter.authenticate()
。
答案 3 :(得分:1)
如果你需要在gui中进行异步操作的结果,那么你需要使用一个回调方法。你需要基本上使用2个runnables。第一个runnable在单独的线程上完成工作。当该工作完成后,结果应该传递给第二个runnable,并传递给SwingUtilities.invokeLater
。第二个runnable将在下一个可用的机会在EDT线程上运行,并可以使用异步操作的结果安全地更新ui。
答案 4 :(得分:1)
如果您不希望UI冻结,您需要执行以下操作:
(来源仅供参考,有编译错误等(为简洁起见))
class Sample {
static final Executor exec = Executors.newCachedThreadPool();
final Adapter adapter = new Adapter();
public Token processRequest(final Email email, final Password password){
Future<Token> future = exec.submit(
new Callable<Token>(){
@Override
public Token call(){
return adapter.authenticate(email, password);
}
});
//do some stuff
if(future.isDone()){
//Ah, it's done.
return future.get();
}
//Not done yet. do some more useful stuff.
//Nothing to do anymore. Just block on the future and
// wait until it's finished.
return future.get();
}
}
当然,您可以将未来存储在与会话关联的某个位置,并且仅在用户请求时返回等。
答案 5 :(得分:0)
您的authenticate()
方法无法返回Token
(除非它可以是占位符对象),因为它可以立即返回,但结果可能尚未发现。
让外部对象实现一个回调方法,比如void authenticationComplete(Token authToken)
,并让你的Runnable
在结果到达时调用该方法。
class Authenticator {
...
public void authenticate(final String email, final String password) {
new Thread(new Runnable() {
public void run() {
Authenticator.this.authenticationComplete(
adapter.authenticate(email, password)
);
}
}).start();
}
public void authenticationComplete(Token authToken) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Update your UI
}
});
}
}