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

Java 如何在异步线程中执行后台计算(在RESTWeb服务中),java,multithreading,web-services,asynchronous,java-threads,Java,Multithreading,Web Services,Asynchronous,Java Threads,我有一个RESTWeb服务,它满足HTTP请求。从数据库获取数据后,我想运行一个后台线程并开始分析数据,这需要一些额外的时间来完成。这些数据与响应无关,我们只是记录计算分析 基于我对线程概念的理解,我尝试了以下方法。但在这两种情况下,HTTP响应都是在后台计算完成后返回的,因此计算线程和原始线程基本上不是异步的,计算线程将停止响应线程,直到分析完成 启动了一个守护进程线程。我希望守护进程线程在后台运行,同时HTTP方法发送响应。但事实并非如此。只有在此线程中完成计算后,才会显示响应。即使父线程退

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

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

  • 启动了一个守护进程线程。我希望守护进程线程在后台运行,同时HTTP方法发送响应。但事实并非如此。只有在此线程中完成计算后,才会显示响应。即使父线程退出,守护进程线程也不应该在后台运行吗?(请阅读james的评论,了解如何启动守护程序可能是一个问题)

    Callable computeCallable=new CallableComputeProcess()
    线程t=新线程(可计算调用)
    t、 setDaemon(true)
    t、 start()

  • 注意:计算线程是我在父线程中创建的子线程


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

    回答我自己的问题:

    我使用了FutureTask概念和ExecutorService,我从不调用get()方法。正如我们所知道的那样。由于我从未调用get()方法,因此计算线程在后台运行,同时返回HTTP响应。它继续在后台运行,直到计算结束

    ExecutorService executor = Executors.newFixedThreadPool(1);
    
    Callable<Boolean> computeCallable = new CallableComputeProcess();
    
    executor.submit(scimCallable);
    
    ExecutorService executor=Executors.newFixedThreadPool(1);
    Callable computeCallable=新的CallableComputeProcess();
    执行人提交(scimCallable);
    
    CallableComputeProcess如下所示:

    public class CallableComputeProcess implements Callable<Boolean> {
    public Boolean call() {
            //do computation
            return true;
        }
    }
    
    公共类CallableComputeProcess实现可调用{
    公共布尔调用(){
    //计算
    返回true;
    }
    }
    

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

    要获得更大的灵活性,请尝试rxJava:

    Flowable.fromCallable(()->{
    Thread.sleep(1000);//模拟昂贵的计算
    返回“完成”;
    })
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.single())
    
    .subscribe(System.out::println,Throwable::printStackTrace)Re,“我希望守护进程线程…但是,…”如果您希望有人解释为什么您的代码会这样做,那么您必须向我们展示代码。当然@jameslarge。立即添加代码.Re,“启动了一个守护进程线程”。如果这意味着您调用了
    t.setDaemon()
    ,那么这可能是个坏主意。在Java术语中,“守护进程”线程是一个线程,如果程序中没有其他非守护进程线程运行,它将被自动终止。您可能不希望线程在执行有用的计算时自动终止。只有当线程的唯一目的是向其他线程提供服务时,才应该调用
    setDaemon()
    。“daemon”线程是一个线程,如果程序中没有其他非守护线程运行,它将被自动终止。谢谢@jameslarge提供的信息。即使成功了,那也是一个大错误。谢谢你@dres。可能需要一些时间来实现这一点,因为该项目是在Java1.7:)除了没有lambda之外,它与示例是一样的。只需构造一个新的匿名可调用函数。