将来有结果吗? [英] Getting a result in the future?

查看:82
本文介绍了将来有结果吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法的结果,该方法可能需要一段时间才能完成,并且实际上并未返回该对象,因此我想尽可能有效地对其进行处理.这是我要实现的目标的一个示例:

I'm looking to get a result from a method which can take a while to complete and doesn't actually return the object, so I'd like to deal with it as effectively as possible. Here's an example of what I'm trying to achieve:

    public static void main (String[] args) {
        Object obj = someMethod();

        System.out.println("The object is" + obj + ", wooh!");
    }

    public void callObject() {
        // Sends request for the object
    }

    public void receiveObject(Object object) {
        // Received the object
    }

    public Object someMethod() {
        callObject();
        // delay whilst the object is being received
        // return received object once received, but how?
    }

方法callObject将调用以获取对象,但是在对象中调用了另一个方法.我希望someMethod()能够调用该对象,然后返回其最终接收到的内容,即使实际调用和接收是单独的方法.

The method callObject will call to get the object, however a different method is called with the object in. I want someMethod() to be able to call for the object, and then return what it eventually receives, even though the actual call and receive are separate methods.

我已经研究过使用FutureTasks和Callables,我认为它们是前进的方向,但我不太确定如何实现它.

I've looked into using FutureTasks and Callables which I think is the way forward, I'm just not too sure how to implement it.

对不起,如果我对自己的解释不够好,如有必要,我会提供更多信息.

Sorry if I didn't explain myself too well, I'll give more information if necessary.

谢谢!

推荐答案

您可以编写一个方法,该方法可以异步执行一些长期运行的任务.然后,您将返回一个将来的对象,该对象为空,但在长时间运行的任务完成后会被填充.在其他编程语言中,这称为承诺".

You could write a method, that kicks of some long running task asynchronously. You would then return a future object, that is empty but gets filled when the long running task is completed. In other programming languages, this is called a promise.

这是一个简单的例子.我创建了一个名为 someLongAsyncOperation 的方法,该方法执行需要一些时间的东西.为了模拟这一点,我只是睡了三秒钟才产生答案.

Here is an simple example. I created a method called someLongAsyncOperation which executes something that takes a while. To simulate this, I just sleep for 3 seconds before generating an answer.

import java.util.UUID;
import java.util.concurrent.*;

public class Test {

    private static final ExecutorService executorService = Executors.newSingleThreadExecutor();

    public Future<MyAnswer> someLongAsyncOperation(){

        Future<MyAnswer> future = executorService.submit(() -> {
            Thread.sleep(3000);
            return new MyAnswer(UUID.randomUUID().toString());
        });

        return future;
    }


    public static void main(String[] args) throws Exception {

        System.out.println("calling someLongAsyncOperation ...");
        Future<MyAnswer> future = new Test().someLongAsyncOperation();
        System.out.println("calling someLongAsyncOperation done.");

        // do something else

        System.out.println("wait for answer ...");
        MyAnswer myAnswer = future.get();
        System.out.printf("wait for answer done. Answer is: %s", myAnswer.value);

        executorService.shutdown();
    }

    static class MyAnswer {
        final String value;

        MyAnswer(String value) {
            this.value = value;
        }
    }
  }

如果执行这个小的测试类,您会看到 someLongAsyncOperation 快速返回,但是当调用 future.get(); 时,我们等待操作完成.

If you execute this little test class, you'll see, that someLongAsyncOperation returns fast, but when calling future.get(); we wait for the operation to complete.

您现在可以执行多个longAsyncOperation的启动之类的操作,因此它们可以并行运行.然后等待所有这些操作完成.

You could now do something like starting of more than one longAsyncOperation, so they would run in parallel. And then wait until all of them are done.

这是您的起点吗?

编辑

您可以像这样实现 someMethod :

public MyAnswer someMethod() throws ExecutionException, InterruptedException {
        Future<MyAnswer> future = someLongAsyncOperation(); // kick of async operation
        return future.get(); // wait for result
    }

将通过调用异步操作并等待结果来再次使其异步.

Which will make the async operation synchron again, by calling it and waiting for the result.

EDIT2

这是另一个使用等待/通知的示例:

Here's another example that uses wait/notify:

import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test2 {

    private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
    private Object receivedObject;
    private final Object mutex = new Object();

    public static void main (String[] args) throws InterruptedException {
        Object obj = new Test2().someMethod();

        System.out.println("The object is" + obj + ", wooh!");

        executorService.shutdown();
    }

    public void callObject() {

        System.out.println("callObject ...");

        // Sends request for the object asynchronously!
        executorService.submit(() -> {

            // some wait time to simulate slow request
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // provide object to callback
            receiveObject(UUID.randomUUID().toString());
        });

        System.out.println("callObject done.");
    }

    public void receiveObject(Object object) {

        System.out.println("receiveObject ...");

        synchronized (mutex) {
            this.receivedObject = object;
            mutex.notify();
        }

        System.out.println("receiveObject done.");
    }

    public Object someMethod() throws InterruptedException {

        System.out.println("someMethod ...");

        synchronized (mutex) {
            callObject();
            while(this.receivedObject == null){
                mutex.wait();
            }
        }

        System.out.println("someMethod done.");
        return this.receivedObject;
    }

}

someMethod 等待,直到 receivedObject 存在. receiveObject 会在到达时通知.

someMethod waits until receivedObject exists. receiveObject notifies upon arrival.

这篇关于将来有结果吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆