2017-02-16 52 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; 
    } 
} 

这不会停止/妨碍其进行响应,并在后台运行的主线程。