2

У меня есть веб-служба REST, которая обслуживает HTTP-запросы. После того, как данные извлекаются из базы данных, я хотел бы запустить фоновый поток и начать анализ данных, для чего требуется некоторое дополнительное время. И эти данные не имеют никакого отношения к ответу, мы просто регистрируем вычисляемый анализ.Как выполнить фоновые вычисления в асинхронном потоке (в веб-службе REST) ​​

Я пробовал следующий метод, основанный на моем собственном понимании концепции Threads. Но в обоих случаях HTTP-ответ возвращается сразу после завершения фонового вычисления, поэтому в основном поток вычислений и исходный поток не являются асинхронными, и поток вычислений останавливает поток ответов до тех пор, пока анализ не будет выполнен.

  1. Начато нить демона. Я ожидал, что поток демона будет запущен в фоновом режиме, а HTTP-метод отправит ответ. Но это не так. Ответ отображается только после того, как вычисление выполняется в этом потоке. Не предполагается ли, что потоки демона выполняются в фоновом режиме, даже когда родительский поток завершается? (Пожалуйста, прочитайте комментарии Джеймсу, чтобы узнать, как начать демон, возможно, была проблема здесь)

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

P.S: Исчисление нить ребенок нить я создал внутри родительского потока.

Есть ли способ запустить поток асинхронно, что позволяет фоновым вычислениям запускаться только в фоновом режиме без остановки ответа HTTP?

+1

Re: "Я ожидал, что демон нить ... Но ..." Если вы хотите, чтобы кто-то объясните, почему ваш код сделал все, что он сделал, тогда вам нужно будет показать нам код. –

+0

Несомненно @jameslarge. Добавление кода через мгновение. – kai

+1

Re, «Начал поток демона». Если это означает, что вы вызвали 't.setDaemon()', то это, вероятно, плохая идея. В терминологии Java поток «daemon» - это поток, который будет автоматически убит, если в программе не осталось других ничейных нитей. Вероятно, вы не хотите, чтобы поток был автоматически убит, пока он делает полезное вычисление. Вы должны только называть '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

это будет то же самое, что и пример, за исключением лямбда. просто создайте новый анонимный вызываемый. – dres

0

Отвечая на мой собственный вопрос:

Я использовал FutureTask концепцию и ExecutorService, на котором я никогда не называю получить метод(). Как известно, 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; 
    } 
} 

Это не мешает/мешать основной поток, который выполняет ответ и работает в фоновом режиме.

Смежные вопросы