![](/img/trans.png)
[英]ExecutorService.submit(Task) vs CompletableFuture.supplyAsync(Task, Executor)
[英]ExecutorService.submit() not returning after submitting the task
我想對函數進行異步調用,然后返回而不等待結果(在Java中)。 我為此編寫的代碼是:
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(new Callable<Void>()
{
public Void call() throws Exception, TimeoutException {
hostNetworkSystem.updatePortGroup("Management Network", spec);
return null;
}
});
我已經嘗試了Runnable和Callable,但是當我在Eclipse中通過代碼調試時,線程被卡在call()函數中,在提交任務后不會立即返回。
我在這里想念什么嗎?
它卡在:
hostNetworkSystem.updatePortGroup("Management Network", spec);
確切地說。 根據我看到的結果,該操作已執行,但並未從此處返回。
為了更好地理解,這是整個調用的外觀:
public void main()
{
try {
AsyncCall asyncCalls = new AsyncCall();
List<PortGroupData> portData = asyncCalls.updatePortGroupFuture(hostNetworkSystem, portGroupName,
portGroupData, modelType, oobmStatus, vlanID);
return portData;
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("InterruptedException " + e.getMessage().toString());
} catch (ExecutionException e) {
System.out.println("ExecutionException " + e.getMessage().toString());
e.printStackTrace();
} catch (Exception e) {
System.out.println("Exception " + e.getMessage().toString());
e.printStackTrace();
}
}
public void updatePortGroupFuture(final HostNetworkSystem hostNetworkSystem,
final String portGroupName, final NetworkParameters networkData, final String modelType,
final boolean oobmStatus, int vlanID) throws InterruptedException, ExecutionException, Exception
{
<some other actions>
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(new Callable<Void>()
{
public Void call() throws Exception, TimeoutException {
hostNetworkSystem.updatePortGroup("Management Network", spec);
return null;
}
});
return;
}
將您的代碼更改為
Future<Void> future = executorService.submit(new Callable<Void>()
{
public Void call() throws Exception, TimeoutException {
System.out.println("before call");
hostNetworkSystem.updatePortGroup("Management Network", spec);
System.out.println("after call");
return null;
}
});
try{
result = future.get(5000, TimeUnit.MILLISECONDS);
}catch(TimeoutException e){
System.out.println("Time out after 5 seconds");
futureResult.cancel(true);
}catch(InterruptedException ie){
System.out.println("Error: Interrupted");
}catch(ExecutionException ee){
System.out.println("Error: Execution interrupted");
}
如果獲得TimeoutException
,請將超時值更改為一個較大的數字。 檢查通話前和通話后語句。 如果您在呼叫之前到達,而在呼叫之后沒有到達,則意味着發生了一些異常。
要知道異常,請將submit()
更改為execute()
並捕獲異常。
submit()
吞下異常。 看一下這段代碼
**Inside FutureTask$Sync**
void innerRun() {
if (!compareAndSetState(READY, RUNNING))
return;
runner = Thread.currentThread();
if (getState() == RUNNING) { // recheck after setting thread
V result;
try {
result = callable.call();
} catch (Throwable ex) {
setException(ex);
return;
}
set(result);
} else {
releaseShared(0); // cancel
}
}
protected void setException(Throwable t) {
sync.innerSetException(t);
}
看一下這個SE帖子和這個SE問題:
嘗試將sysout放在commit(...)之后,看是否能打印出來。 這表明父/主線程未在call()方法上被阻塞,並在提交任務后立即返回。
您可以捕獲submit方法返回的Future,並在submit方法調用之后添加以下代碼:
try {
future.get();
}catch(ExecutionException ee){
System.out.println("exception >>" + ee.getMessage());
}
service.shutdown();
由於future.get是一個阻塞調用,因此提交任務的線程將等待異步操作完成。 您還將了解它是否拋出任何異常。
FutureTask將異常存儲在變量中,然后將其包裝在ExecutionException中,並在調用get方法時引發該異常。 因此,即使我們在FutureTask上調用get()方法,我們也可以獲得底層異常
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.