2017-07-14 52 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