Java 从异步调用run方法返回一个值

Java 从异步调用run方法返回一个值,java,eclipse,eclipse-plugin,Java,Eclipse,Eclipse Plugin,我有一个必须返回布尔值的方法。该方法具有对run方法的异步调用。在run方法中,我必须在封闭方法中设置变量。下面是我的代码 private boolean isTrue() { boolean userAnswer; Display.getDefault().asyncExec(new Runnable() { public void run() { userAnswer = MessageDialog.openQuestion(new S

我有一个必须返回布尔值的方法。该方法具有对run方法的异步调用。在run方法中,我必须在封闭方法中设置变量。下面是我的代码

private boolean isTrue() {
    boolean userAnswer;
    Display.getDefault().asyncExec(new Runnable() {
        public void run() {
            userAnswer = MessageDialog.openQuestion(new Shell(), "some message", "some question?");
        }
    });
    return userAnswer;
}   

这段代码给出了一个错误--“userAnswer”必须是final,如果我把它设为final,我就不能给它赋值。请建议处理此情况的方法。

您可以查看界面:

未来表示异步计算的结果。方法 用于检查计算是否完成,以等待其完成 完成,并检索计算结果。结果 只能在计算已完成时使用方法get检索 完成,必要时阻塞,直到准备就绪。取消是 通过取消方法执行。还提供了其他方法来 确定任务是否正常完成或已取消。每年一次 计算已完成,无法取消计算。如果你 为了可取消性而希望使用未来,但不是 提供一个可用的结果,您可以在将来声明表单的类型 并作为基础任务的结果返回null


有很多模式可以实现这一点。也许最简单的方法是使用某种回调函数,例如:

interface Callback {
    void onSuccess(boolean value);
}

private boolean isTrue(final Callback callback) {
Display.getDefault().asyncExec(new Runnable() {
    public void run() {
        boolean userAnswer = MessageDialog.openQuestion(new Shell(), "some message", "some question?");
        callback.onSuccess(userAnswer);   
    }
});
}

并调用如下方法:

isTrue(new Callback() {
            @Override
            public void onSuccess(boolean value) {
                // do some stuff
            }
        });

如果需要将
Callable
调整为
Runnable
,可以使用
java.util.concurrent.FutureTask

public class UserQuestion implements Callable<Boolean> {

    private String message;
    private String question;

    public UserQuestion(String message, String question) {
        this.message = message;
        this.question = question;
    }

    public Boolean call() throws Exception {
        boolean userAnswer = MessageDialog.openQuestion(new Shell(),
                message, question);
        return Boolean.valueOf(userAnswer);

    }
}

UserQuestion userQuestion = new UserQuestion("some message", "some question?");
FutureTask<Boolean> futureUserAnswer = new FutureTask<Boolean>(userQuestion);
Display.getDefault().asyncExec(futureUserAnswer);
Boolean userAnswer = futureUserAnswer.get();
public类UserQuestion实现可调用{
私有字符串消息;
私有字符串问题;
公共用户问题(字符串消息,字符串问题){
this.message=消息;
这个问题=问题;
}
公共布尔调用()引发异常{
boolean userAnswer=MessageDialog.openQuestion(新Shell(),
信息、问题);
返回Boolean.valueOf(userAnswer);
}
}
UserQuestion UserQuestion=newuserquestion(“一些消息”,“一些问题?”);
FutureTask futureUserAnswer=新的FutureTask(userQuestion);
Display.getDefault().asyncExec(futureUserAnswer);
布尔userAnswer=futureUserAnswer.get();

除了语法错误之外,问题是布尔值将在异步调用返回之前返回。因此,不确定您对该方法的期望是什么…问题中的方法就是您想要的。但请注意,这将阻止等待执行
futureUserAnswer
,因此您也可以使用
syncExec
@aim的答案在这里更有用。是的,这是真的。因此,您应该通过isDone()方法轮询未来,或者在单独的线程(当然不是ui线程)中轮询未来。也可以建议使用重载get(长超时)方法。我也同意回调可能更好。这个方法onSucess()将被异步调用,我需要主线程中的值。如果我创建一个全局/实例变量并为其指定布尔值。主线程仍然不知道何时赋值,何时读取全局值。你仔细考虑过你的答案了吗?