我想对函数进行异步调用并返回而不等待结果(在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中的代码进行调试时,线程在调用时被卡住()函数在提交任务后没有立即返回。
我在这里错过了什么吗?
它陷入了:
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;
}
答案 0 :(得分:1)
将您的代码更改为
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
,请将超时值更改为某个较大的数字。
在通话前检查&amp;电话结束后。如果你在通话前得到并且没有接到电话,则意味着发生了一些异常。
要了解该异常,请将submit()
更改为execute()
并捕获异常。
submit()
吞下例外情况。看看这个code
**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 Post和这个SE问题:
Choose between ExecutorService's submit and ExecutorService's execute
答案 1 :(得分:0)
尝试在提交(...)后输入一个sysout,看看是否打印出来。这表示父/主线程未在call()方法中被阻止,并在提交任务后立即返回。
答案 2 :(得分:0)
您可以捕获submit方法返回的Future,并在submit方法调用后添加以下代码:
try {
future.get();
}catch(ExecutionException ee){
System.out.println("exception >>" + ee.getMessage());
}
service.shutdown();
由于future.get是一个阻塞调用,提交任务的线程将等待异步操作完成。你也会知道它是否会抛出任何例外。
FutureTask将异常存储在一个变量中,该变量随后将被包装在ExecutionException中,并在调用get方法时抛出。因此,即使我们在FutureTask上调用get()方法
,我们也可以获得底层异常