Как работает ExecutorService при отправке вызываемой задачи с обратным вызовом - PullRequest
0 голосов
/ 10 октября 2019

Как добавить пользовательскую проверку в обратном вызове executorService.submit (). Я хочу, чтобы моя ветка ничего не делала, когда флаг имеет значение true. Если флаг равен false, он должен работать как обычно.

import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class test{
    private static volatile boolean flag= false;
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Boolean> callableTask = () -> {
            return isFlag();
        };
        Future a = submitAsync(callableTask);
        System.out.println("tartest"+a.get());
    }
    public static  Future submitAsync(Callable taskToRun) {
        ExecutorService e1 =  Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder().namingPattern("").build());
        return e1.submit(() -> {
            try {
                if (flag) {
                    return;
                }
                taskToRun.call();
            } catch (Exception e) {
                System.out.println("garbage ---");
            }
        });
        // return e1.submit(taskToRun);
    }
    public static boolean isFlag() {
        return true;
    }
}

Здесь a.get () возвращает ноль. Если я заменю e1.submit (....) на e1.submit (taskToRun), который комментируется в данном фрагменте кода, то он работает нормально. Так почему a.get () имеет значение null?

Ответы [ 2 ]

2 голосов
/ 10 октября 2019
return e1.submit(() -> {
    try {
        if (flag) {
            return;
        }
        taskToRun.call();
    } catch (Exception e) {
        System.out.println("garbage ---");
    }
});

В этом фрагменте лямбда, переданная методу submit в ExecutorService e1, интерпретируется как Runnable, поэтому возвращаемое значение равно null. Проверьте эту документацию для более подробной информации. Вам нужно передать вызываемый taskToRun сам по себе e1.submit(), чтобы иметь возможность получить возвращаемое значение вызываемого. Кроме того, было бы чище поместить логику в саму Callable. Я переписал пример кода, чтобы удовлетворить ваши требования.

package stackoverflow.test;

import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class test{

  private static volatile boolean flag = true;

  public static void main(String[] args) throws ExecutionException, InterruptedException {

    Callable<Boolean> callableTask = () -> {
      if (flag) {
        System.out.println("Flag is true, returning without executing callable logic !");
        return false;
      }
      System.out.println("Flag is false, executing callable logic !");
      return isFlag();
    };

    Future a = submitAsync(callableTask);
    System.out.println("test " + a.get());
  }

  private static  Future<Boolean> submitAsync(Callable<Boolean> taskToRun) {
    ExecutorService e1 =  Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder().namingPattern("").build());

    return e1.submit(taskToRun);
  }

  private static boolean isFlag() {
    return true;
  }
}
0 голосов
/ 10 октября 2019

Ваш метод submitAsync возвращает Future, который является результатом вызова ExecutorService.submit (Runnable). Начиная с документация по этому методу :

Отправляет задачу Runnable для выполнения и возвращает Future, представляющий эту задачу. Метод get Future вернет значение NULL при успешном завершении.

Если вы хотите вернуть Future, который возвращает значение, добавьте операторы return в вашу лямбду, чтобы он был интерпретированкак вызываемый вместо бегущего:

    return taskToRun.call();
} catch (Exception e) {
    e.printStackTrace();
    return null;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...