Why scheduleAtFixedRate - scheduleWithFixedDelay methods do not use Callable <V>

I am doing some experiments about concurrency in Java 8

In ScheduledThreadPoolExecutor API

I see the following two signatures:

schedule(Callable<V> callable, long delay, TimeUnit unit) schedule(Runnable command, long delay, TimeUnit unit) 

One for Callable and one for Runnable

I see the following two in the API:

 scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 

My question is: why there are no two equivalents for Callable

 scheduleAtFixedRate(Callable<V> callable, long initialDelay, long period, TimeUnit unit) scheduleWithFixedDelay(Callable<V> callable, long initialDelay, long delay, TimeUnit unit) 

I need to get a logical result for the operation.

Thanks.

+6
source share
2 answers

What do you expect from the scheduleAtFixedRate(Callable<V>) return type? The return type of schedule(Callable<V>) is Future<V> , indicating that at some point in the future, a value of type V returned by the called will be available. You can wait for this value to be available by calling get() in the Future.

The return type scheduleAtFixedRate(Callable<V>) cannot be something like Future<List<V>> , since this means that at some point in the future, all values ​​returned by repeated calls to the called are available. However, there will always be more scheduled planned runs, so this list will never exist.

What you need for something like this is the concept of an asynchronous stream of results, under which you can subscribe so that you process each result as it arrives. As far as I know, this does not exist in the standard library. One of the third-party libraries that I know contains things like Netflix RxJava . Using, for example, ReplaySubject from this library, you can create a stream of results and process each result as it returns:

 import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import rx.subjects.ReplaySubject; public class Callables { public static void main(String[] args) { // Example Callable that returns a boolean result Random random = new Random(); Callable<Boolean> callable = () -> random.nextBoolean(); // Turn the Callable into a Runnable that adds the last result to the stream of results ReplaySubject<Boolean> results = ReplaySubject.create(); Runnable runnable = () -> { try { boolean result = callable.call(); results.onNext(result); } catch (Exception e) { // Needed since Callable can throw an exception, but Runnable cannot } }; // Periodically run the Runnable ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); executor.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS); // Handling the results as they arrive results.forEach(result -> System.out.println("Result: " + result)); System.out.println("Waiting for results..."); } } 

If you decide to use RxJava, it might be worth using more of your API instead of using Executor directly. You can use Observable.interval to generate a stream periodically emitting a number, then match it to call the called one. This way you get the same stream of results in a more concise way:

 import java.io.IOException; import java.util.Random; import java.util.concurrent.TimeUnit; import rx.Observable; public class MoreCallables { public static void main(String[] args) throws IOException { Observable<Long> periodic = Observable.interval(1, TimeUnit.SECONDS); Random random = new Random(); Observable<Boolean> results = periodic.map(i -> random.nextBoolean()); results.forEach(result -> System.out.println("Result: " + result)); System.out.println("Waiting for results..."); System.in.read(); } } 
+12
source

following the @andersschuller solution, a more concise form might look like this:

 Observable.interval(1, TimeUnit.SECONDS) .map((Long i) -> "tick " + i) .forEach(result -> System.out.println("Result: " + result)); 
0
source

Source: https://habr.com/ru/post/973059/


All Articles