[英]Get result from call that doesn't return result?
我正在使用一個可以調用結果的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的結果,但不確定如何實現它們。
任何想法? 謝謝!
這個怎么樣。 在您的班級中引入一個新字段:
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
方法中完成該將來,並在someMethod
等待它( .get()
it)。 這比使用線程睡眠循環更慣用。
最簡單的情況:您以普通的阻止方式發送請求,並希望能夠在執行過程中在主線程上執行某些操作。 為此,請使用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兩者都做)。
如何返回什么都沒有返回的東西,如何return
單詞的someMethod()
,而callObject()
什么也不返回,因為它是void
。 這樣它將返回一個對象
public Object someMethod() {
return new Object();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.