簡體   English   中英

提交任務后未返回ExecutorService.submit()

[英]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");
            }
  1. 如果獲得TimeoutException ,請將超時值更改為一個較大的數字。 檢查通話前和通話后語句。 如果您在呼叫之前到達,而在呼叫之后沒有到達,則意味着發生了一些異常。

  2. 要知道異常,請將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問題:

在ExecutorService的提交和ExecutorService的執行之間選擇

嘗試將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM