2017-02-22 17 views
1

所以我用代碼的工作有點像這樣:如果我依賴慢速服務,我該如何避免花費處理器等待它的時間?

public void callSlowService(List<Object> objectsToCallFor) { 
    objectsToCallFor 
     .parallelStream() 
     .forEach(object -> slowService.call(object)) 
} 

凡slowService.call花費〜100-500ms

的問題是,我可以並行所有我想要的,但在年底那天我仍然鎖定了一個線程,等待500毫秒,我的CPU還有其他線程可以做的其他事情。

假設我無法改變這個其他服務(我不能),有沒有其他設計可以在我的身邊使用,這樣我的CPU就可以在等待slowService的響應時做其他事情嗎?

+2

如果你打電話來訪問服務的內容是合理的,你就是阻塞,而不是花費處理器時間。 – EJP

+0

是的,我真的不會擔心一個正在等待的線程。線程是輕量級的(與進程不同),並且在虛擬機扼殺之前可以有數千個線程。 – john16384

回答

0

你不行。

但是,您可以緩解問題。使用通過的BlockingQueue饋送的一個新線程,並在結果到達時爲另一個隊列提供結果。

您仍然會等待結果所需的時間,但至少您的主要處理過程將繼續進行。

0

如果我正確理解你,你想使這個方法異步。如果您不需要結果並且想要跳過錯誤處理,則可能需要在新線程中啓動代碼。 像:

public void callSlowService(final List<Object> objectsToCallFor) { 
    new Thread(() -> { 
     objectsToCallFor 
      .parallelStream() 
      .forEach(object -> slowService.call(object)); 
    }).start(); 
} 

另一個(更好)的方式 - 使用線程池。使用parallelStream() - >你會小心,那麼你將使用共享的ForkJoinPool,這可能會影響應用程序的性能。使用舊的好緩存線程池或任何其他線程池實現取決於項目需求會更安全。

public ExecutorService executor = Executors.newCachedThreadPool(); 

public void callSlowService(final List<Object> objectsToCallFor) { 
    for (Object obj : objectsToCallFor) { 
     executor.submit(() -> { 
      objectsToCallFor 
       .parallelStream() 
       .forEach(object -> slowService.call(object)); 
     }); 
    } 
} 

其實很少有其他的方式可以用更漂亮的方式來製作類似的東西,但是這也可以起作用。

相關問題