gpt4 book ai didi

java - 将来有结果?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:49:56 24 4
gpt4 key购买 nike

我希望从一个方法中获得结果,该方法可能需要一段时间才能完成并且实际上不会返回对象,因此我想尽可能有效地处理它。这是我要实现的目标的示例:

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

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

抱歉,如果我没有很好地解释自己,如有必要,我会提供更多信息。

谢谢!

最佳答案

您可以编写一个方法,异步启动一些长时间运行的任务。然后你会返回一个 future 的对象,它是空的但在长时间运行的任务完成时被填充。在其他编程语言中,这称为 promise 。

这是一个简单的例子。我创建了一个名为 someLongAsyncOperation 的方法,它执行需要一段时间的操作。为了模拟这一点,我在生成答案之前只睡了 3 秒钟。

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(); 时,我们等待操作完成。

您现在可以执行一些操作,例如启动多个 longAsyncOperation,以便它们并行运行。然后等到所有这些都完成。

这对您来说是一个起点吗?

编辑

你可以像这样实现someMethod:

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

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

EDIT2

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

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 到达时通知。

关于java - 将来有结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34269015/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com