简体   繁体   中英

Periodically running a Callable via ScheduledExecutorService

I have a Callable<String> . I want to run it periodically via ScheduledExecutorService.scheduleAtFixedRate() , and to get a list of all the Strings that were returned by the .call() invocations on my callable. As scheduleAtFixedRate does not take a Callable (only Runnable s) I need to roll out a custom Runnable that wraps my Callable , something along these lines:

final Callable<String> myCallable = ....;
final ConcurrentLinkedQueue<String> results 
  = new ConcurrentLinkedQueue<String>();

Runnable r = new Runnable() {
  @Override public void run() {
    try {
      results.add(myCallable.call());
    } catch (Exception e) { 
      results.add(null);  // Assuming I want to know that an invocation failed
    }
  }
};

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(r, 0, 1, TimeUnit.SECONDS);

Naturally, I'd like to avoid rolling out my own custom thingies (especially in multi-threaded code), so I wonder there is a JDK class that does this kind of aggregation?

What you are doing above is treating your Callable implementation as just another normal class. You are not submitting the callable to a ThreadPool executor. Calling Callable.call() doesn't utilize the ThreadPoolExecutor.

You need to submit your Task (Runnable/Callable/ForkJoinTask,etc..) to a ThreadPool to utilize the thread pooling. You can use the Futures to collect the results once executed.

ForkJoinPool is one option you can try thats part of JDK 7. Fork the tasks and Join them using ForkJoinTask Why not use Futures? They are exactly meant for knowing the state of Task and its result.

Did you look at this : Using Callable to Return Results From Runnables

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM