2017-07-14 56 views
-1

我想在我的Java程序中使用兩個線程來處理一小部分。我需要給數據庫第一次調用和第二次調用API,兩次調用具有相同的輸入,然後使用任何先前完成的線程的輸出。使用2線程的更快輸出

這是我第一次用線程編程,我很困惑。我看過教程,他們主要解釋如何用線程完成兩件獨立的事情,所以我有點迷路。

有人可以幫助或重新指引我到他們可能有的任何有用的鏈接?

到目前爲止,據我瞭解,它應該看起來像這樣嗎? :

Thread thread1 = new Thread(func1()); 
Thread thread2 = new Thread(func2()); 
thread1.start(); 
thread2.start(); 

但是那麼我該如何提取函數的輸出呢?我怎麼知道哪一個先完成? (!爲幫助約翰感謝)

----------- UPDATE 1 ---------

試圖CompletableFuture後,我有這樣的事情:

CompletableFuture<Object> getData = CompletableFuture.anyOf(
     CompletableFuture.runAsync(() -> getDataFromDB(clientData)), 
     CompletableFuture.runAsync(() -> getDataFromApi(clientData)) 
    ); 

    getData.thenApply(dataObject -> { 
     // Cast the returned Object to the actual type of your data, 
     // assuming both getDataFromDb and getDataFromApi 
     // return the same result type 
     Object data = (String) dataObject; 

     // Work with the returned data. 
     result = (String) data; 
    }); 

但我得到這個錯誤getData.thenApply():

方法thenApply(功能)的類型CompletableFuture不適用的參數((dataObject時) - > {})

因爲我知道String類型的getData中,將它轉換爲String並存儲結果會好嗎?

+0

您是否聽說過「Callables」?它就像一個'Runnable',但它可以返回一個值。 – Tavo

+0

您是否考慮過使用[RxJava](http://reactivex.io/)?這只是你的第一個多線程方法,它可能有點矯枉過正,但它有很好的運營商來處理這種情況 – Pelocho

+0

@Tavo謝謝!我也仔細研究過,並嘗試過,但無法實現。 – Padfoot

回答

0

由於@Johan赫希建議用CompletableFuture嘗試。我只是試試這個和它的作品:

CompletableFuture.anyOf(
      CompletableFuture.supplyAsync(() -> getDataFromDB(clientData)), 
      CompletableFuture.supplyAsync(() -> getDataFromApi(clientData))) 
      .thenApply(item -> (String) item) 
      .thenAccept(result -> { 
       // Consume the data 
       System.out.println(result); 
      }); 

要注意的是我目前消耗數據,因此不會返回任何東西。如果您只是想將結果傳遞給另一個CompletableFuturethenAccept方法更改爲thenApply

+0

謝謝!!!有效! – Padfoot

0

您可以使用ExecutorService.invokeAny

執行給定的任務,返回一個已成功完成(即未拋出異常)的結果,如果任何事情。在正常或異常返回時,尚未完成的任務將被取消。如果在進行此操作時修改了給定集合,則此方法的結果未定義。

+0

謝謝!我看着它,但似乎無法得到正確的參數。 – Padfoot

0

Java 8提供了一個非常好的utility class called CompletableFuture,它可以幫助你的情況。

創建兩個CompletableFuture,每個任務一個,然後使用CompletableFuture.anyOf方法等待任一個完成。

CompletableFuture<TData> getData = CompletableFuture.anyOf(
    CompletableFuture.runAsync(() -> getDataFromDb()), 
    CompletableFuture.runAsync(() -> getDataFromApi()) 
); 

getData.thenApply(dataObject -> { 
    // Cast the returned Object to the actual type of your data, 
    // assuming both getDataFromDb and getDataFromApi 
    // return the same result type 
    TData data = (TData)dataObject; 

    // Work with the returned data. 
    processData(data); 
}); 
+0

我試過了,但getData.thenApply()出現錯誤: _「方法thenApply(Function <?super Object,?extends U> ) - > {})「_ 我的數據都在字符串中,但它不會讓我把TData設置爲字符串...我做錯了什麼? – Padfoot