SmartGridready / SGrJava

SmartGridready communication handler in Java
Other
0 stars 0 forks source link

Using JAVA Futures for non blocking Asynchronous versions of getVal and setVal #2

Open ChrisBroenni opened 2 years ago

ChrisBroenni commented 2 years ago

SNIP from Stackoverflow https://stackoverflow.com/questions/31092067/method-call-to-future-get-blocks-is-that-really-desirable

The idea is that you would submit multiple tasks and then wait. You are right that if you wait for the result in between submitting each task, then they will be processed in serial and you won't gain anything. – Yosef Weiner Jun 27, 2015 at 18:39

@SkinnyJ If multiple tasks are submitted, how do you know the result returned is for which task? And how do i wait for multiple tasks? – TheMonkWhoSoldHisCode Jun 27, 2015 at 18:44

@VishalP You will then have list of Futures which you could check with isDone() or fetch result with get() – John Jun 27, 2015 at 18:47

The simplest is to use (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#invokeAll(java.util.Collection)). Otherwise, you can keep track of each future as you submit its Callable, and get the results one after the other. Either way, the processing is happening in parallel. – Yosef Weiner Jun 27, 2015 at 19:10

The important thing is that "get" is not starting the execution, "submit" is, get is only "waiting" the result. So we could start multiple tasks (multiple executors) and then use get on every one. In that way all the executors will run in parallel. If you can continue without the result instead of get you could use the Observer pattern

Answers

Future offers you method isDone() which is not blocking and returns true if computation has completed, false otherwise. Future.get() is used to retrieve the result of computation. You have a couple of options: • call isDone() and if the result is ready ask for it by invoking get(), notice how there is no blocking • block indefinitely with get() • block for specified timeout with get(long timeout, TimeUnit unit) The whole Future API thing is there to have easy way obtaining values from threads executing parallel tasks. This can be done synchronously or asynchronously if you prefer, as described in bullets above.

UPDATE WITH CACHE EXAMPLE

Here is a cache implementation from Java Concurrency In Practice, an excellent use case for Future. • If the computation is already running, caller interested in result of computation will wait for computation to finish • If the result is ready in the cache, caller will collect it • if the result is not ready and computation has not started yet, caller will start computation and wrap result in Future for other callers. This is all easily achieved with Future API. package net.jcip.examples;

import java.util.concurrent.*; /**

public Memoizer(Computable<A, V> c) { this.c = c; }

public V compute(final A arg) throws InterruptedException { while (true) {

    Future<V> f = cache.get(arg);
    // computation not started
    if (f == null) {
        Callable<V> eval = new Callable<V>() {
            public V call() throws InterruptedException {
                return c.compute(arg);
            }
        };

        FutureTask<V> ft = new FutureTask<V>(eval);
        f = cache.putIfAbsent(arg, ft);
        // start computation if it's not started in the meantime
        if (f == null) {
            f = ft;
            ft.run();
        }
    }