如何在异步线程中执行后台计算(在REST Web服务中)

时间:2017-02-16 16:56:25

标签: java multithreading web-services asynchronous java-threads

我有一个满足HTTP请求的REST Web服务。从数据库中提取数据后,我想运行后台线程并开始分析数据,这需要一些额外的时间来完成。这些数据与响应无关,我们只记录计算分析。

我根据自己对Threads概念的理解尝试了以下方法。但是在这两种情况下,HTTP响应都是在后台计算完成后返回的,所以基本上计算线程和原始线程不是异步的,计算线程正在停止响应线程直到分析完成。

  1. 启动了守护程序线程。我希望守护程序线程在后台运行,同时HTTP方法发送响应。但是,不是真的。只有在此线程中完成计算后才会显示响应。即使父线程退出,是不是守护程序线程应该在后台运行? (请阅读詹姆斯的评论,了解启动守护程序如何成为问题)

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

  2. P.S:计算线程是我在父线程中创建的子线程。

    有没有办法异步启动一个线程,让后台计算只在后台运行而不停止http响应?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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;
    }
}

这不会停止/阻碍执行响应并在后台运行的主线程。