我希望从一个方法得到一个结果可能需要一段时间才能完成并且实际上不会返回该对象,所以我想尽可能有效地处理它.这是我想要实现的一个例子:
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,我认为这是前进的方向,我只是不太确定如何实现它.
对不起,如果我没有解释得太好,我会在必要时提供更多信息.
谢谢!
您可以编写一个方法,以异步方式执行一些长时间运行的任务.然后,您将返回一个未来对象,该对象为空,但在长时间运行的任务完成时会被填充.在其他编程语言中,这称为承诺.
这是一个简单的例子.我创建了一个方法someLongAsyncOperation
来执行需要一段时间的事情.为了模拟这个,我只是在产生答案之前睡了3秒钟.
import java.util.UUID; import java.util.concurrent.*; public class Test { private static final ExecutorService executorService = Executors.newSingleThreadExecutor(); public FuturesomeLongAsyncOperation(){ 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 { Futurefuture = 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
抵达后通知.