2017-02-16 51 views
2

我有一個滿足HTTP請求的REST Web服務。從數據庫中提取數據後,我想運行後臺線程並開始分析數據,這需要花費額外的時間來完成。這些數據與響應無關,我們只記錄計算出的分析結果。如何在異步線程中執行後臺計算(在REST Web服務中)

我根據自己對線程概念的理解,嘗試了以下方法。但是在這兩種情況下,HTTP響應都是在後臺計算完成後返回的,所以基本上計算線程和原始線程不是異步的,並且計算線程正在停止響應線程直到分析完成。

  1. 啓動守護進程線程。我期望守護線程在後臺運行,同時HTTP方法發送響應。但是,並非如此。只有在此線程中完成計算後才顯示響應。即使父線程退出,守護線程是否應該在後臺運行? (請閱讀詹姆斯的意見,知道如何啓動一個守護進程會一直在這裏的一個問題)

    Callable<Boolean> computeCallable = new CallableComputeProcess();
    Thread t=new Thread(computeCallable);
    t.setDaemon(true);
    t.start();

P.S:計算線程是一個子線程我父線程內部創建的。

有沒有辦法異步啓動一個線程,讓後臺運算在後臺運行而不停止http響應?

+1

回覆, 「我預計守護線程來......但是......」 如果你想有人解釋爲什麼你的代碼做了它所做的任何事情,那麼你將不得不向我們展示代碼。 –

+0

Sure @jameslarge。稍後添加代碼。 – kai

+1

Re,「啓動守護程序線程」。如果這意味着你調用了't.setDaemon()',那麼這可能是一個壞主意。在Java的術語中,「守護程序」線程是一個線程,如果程序中沒有其他非守護線程運行,它將自動終止。您可能不希望線程在執行有用的計算時被自動殺死。如果線程的唯一目的是向其他線程提供某種服務,則只應調用setDaemon()。 –

回答

1

更靈活的嘗試rxJava:

Flowable.fromCallable(() -> { 
 
    Thread.sleep(1000); // imitate expensive computation 
 
    return "Done"; 
 
}) 
 
    .subscribeOn(Schedulers.io()) 
 
    .observeOn(Schedulers.single()) 
 
    .subscribe(System.out::println, Throwable::printStackTrace);

https://github.com/ReactiveX/RxJava

+0

謝謝@dres。可能需要一段時間來實現這個,因爲該項目在Java 1.7中:) – kai

+1

它將與示例相同,除了沒有lambda。只是構建一個新的匿名可調用。 – dres

0

回答我的問題:

我用FutureTask概念和ExecutorService的,關於這一點我從來沒有調用get()方法。正如我們所知道的那樣,focus doesn't shift to the thread(with the FutureTask) until we call FutureTask.get() method。由於我從來沒有調用get()方法,所以計算線程在後臺運行,同時返回HTTP響應。它會繼續在後臺運行,直到計算結束。

ExecutorService executor = Executors.newFixedThreadPool(1); 

Callable<Boolean> computeCallable = new CallableComputeProcess(); 

executor.submit(scimCallable); 

而且CallableComputeProcess是這樣的:

public class CallableComputeProcess implements Callable<Boolean> { 
public Boolean call() { 
     //do computation 
     return true; 
    } 
} 

這不會停止/妨礙其進行響應,並在後臺運行的主線程。