sanjiv ranjan
sanjiv ranjan

Reputation: 60

How ExecutorService works when submit a callable task with callback

How to add custom check in executorService.submit() callback. I want my thread not to do anything, whenever flag is true. If flag is false then it should work as usual.

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;
    }
}

Here, a.get() is returning null. If I replace e1.submit(....) with e1.submit(taskToRun), which is commented in given code snippet then its working fine. So why a.get() is null?

Upvotes: 0

Views: 1665

Answers (2)

VGR
VGR

Reputation: 44335

Your submitAsync method returns a Future that is the result of calling ExecutorService.submit(Runnable). From the documentation of that method:

Submits a Runnable task for execution and returns a Future representing that task. The Future's get method will return null upon successful completion.

If you want to return a Future that yields a value, add return statements to your lambda, so it will be interpreted as a Callable instead of a Runnable:

    return taskToRun.call();
} catch (Exception e) {
    e.printStackTrace();
    return null;
}

Upvotes: 0

amyth
amyth

Reputation: 36

return e1.submit(() -> {
    try {
        if (flag) {
            return;
        }
        taskToRun.call();
    } catch (Exception e) {
        System.out.println("garbage ---");
    }
});

In this snippet, the lambda passed to submit method on ExecutorService e1 is interpreted as a Runnable and that is why the return value is null. Check this documentation for more details. You need to pass the callable taskToRun itself to e1.submit() to be able to get the return value of the callable. Also, it would be cleaner to put the logic inside the Callable itself.

I have rewritten the sample code to achieve your requirement.

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;
  }
}

Upvotes: 2

Related Questions