当前位置:  开发笔记 > 编程语言 > 正文

获得未来的结果?

如何解决《获得未来的结果?》经验,为你挑选了1个好方法。

我希望从一个方法得到一个结果可能需要一段时间才能完成并且实际上不会返回该对象,所以我想尽可能有效地处理它.这是我想要实现的一个例子:

    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()能够调用该对象,然后返回它最终收到的内容,即使实际调用和接收是单独的方法.

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

对不起,如果我没有解释得太好,我会在必要时提供更多信息.

谢谢!



1> Tim Büthe..:

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

这是一个简单的例子.我创建了一个方法someLongAsyncOperation来执行需要一段时间的事情.为了模拟这个,我只是在产生答案之前睡了3秒钟.

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

public class Test {

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

    public Future someLongAsyncOperation(){

        Future 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 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();我们等待操作完成.

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

这是否适合您的起点?

编辑

你可以someMethod像这样实现:

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

通过调用异步操作并等待结果,这将再次使异步操作同步.

EDIT2

这是另一个使用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抵达后通知.

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有