我正在使用调用结果的API,但不会返回结果本身。调用完成后,将调用一个包含结果的单独方法(侦听器)。这是我想要实现的一个例子:
public static void main (String[] args) {
Object obj = someMethod();
System.out.println("The object is" + obj + ", wooh!");
}
public void callObject() {
// This is the call that sends a request for the object
}
public void receiveObject(Object object) {
// This is the API method that is invoked with the result (cannot be changed)
}
// What I want to be able to do
public Object someMethod() {
callObject();
// return received object once received, but how?
}
callObject()不返回对象,只启动对它的检索。我想有一个方法来调用对象,然后在收到它时返回它。我一直在研究Callables和Future的结果,但我不确定如何实现它们。
有什么想法吗?谢谢!
答案 0 :(得分:0)
这个怎么样?在课堂上引入一个新领域:
private Object result;
然后在receiveObject(Object object)方法中设置它:
this.result = object;
在someMethod()中:
callObject();
while(this.result==null) {
Thread.sleep(100);
}
Object answer = this.result;
this.result = null;
return answer;
只要为每个API请求创建此类的新实例,该工作正常。不要试图让这个班级成为一个单身人士,它只会让事情变得不必要地复杂化。
如果你真的需要一个单身人士,你可以将private Object result;
概括为一个地图,并想出一种方法来识别每个单独的API调用,就像一些来电者ID一样。
最后,您还可以将private Object result;
替换为java.util.concurrent.CompletableFuture。然后在receiveObject
方法中完成该未来,并在.get()
中等待它(someMethod
)。这比使用线程睡眠循环更加惯用。
答案 1 :(得分:0)
最简单的情况:您以普通的阻止方式发送请求,并希望能够在主线程执行时执行某些操作。为此,请使用ExecutorService
,通常是通过调用Executors
创建的,例如:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class ToyConc1 {
public static void main(String[] args) throws InterruptedException,
ExecutionException {
ExecutorService exec = Executors.newCachedThreadPool();
try {
Callable<String> op1 = new Callable<String>() {
@Override
public String call() throws Exception {
return slowlyGetHttpPage("http://www.google.com");
}
};
Callable<String> op2 = new Callable<String>() {
@Override
public String call() throws Exception {
return slowlyGetHttpPage("http://edition.cnn.com/");
}
};
Future<String> resF1 = exec.submit(op1);
Future<String> resF2 = exec.submit(op2);
for (int i = 0; i < 20; i++) {
System.out.println("doing useful work on the main thread...");
}
System.out.println("The object 1 is " + limit(resF1.get(), 1000) + ", wooh!");
System.out.println("The object 2 is " + limit(resF2.get(), 1000) + ", wooh!");
} finally {
exec.shutdown();
exec.awaitTermination(60, TimeUnit.SECONDS);
}
}
private static String slowlyGetHttpPage(String urlName) throws InterruptedException,
IOException {
Thread.sleep(2000);
URL url = new URL(urlName);
URLConnection conn = url.openConnection();
InputStream in = conn.getInputStream();
InputStreamReader reader = new InputStreamReader(in); // wrong charset maybe
BufferedReader br = new BufferedReader(reader);
StringBuilder sb = new StringBuilder();
try {
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} finally {
br.close();
}
}
private static String limit(String s, int length) {
if (s == null) {
return null;
}
if (s.length() <= length) {
return s;
}
return s.substring(0, length) + " [and " + (s.length() - length) + " more]";
}
}
或者,用于发送请求并返回结果的库/框架/技术可能已经为您提供类似Future
的内容或接受类似回调的内容(例如AsyncHttpClient同时执行)
答案 2 :(得分:-1)
如何返回无法返回的内容,someMethod()
return
字在哪里,callObject()
什么都不返回,因为它是{{1} }。这样它就会返回一个对象
void