Question

I use ScheduledExecutorService and I want it to do some calculation every 10 seconds for a minute and after that minute to return me the new value.How do I do that?

Example: So it receives 5 it adds +1 six times then it should return me after a minute the value of 11.

What i have so far but is not working is:

package com.example.TaxiCabs;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import static java.util.concurrent.TimeUnit.*;


public class WorkingWithTimeActivity {
public int myNr;
public WorkingWithTimeActivity(int nr){
    myNr = nr;
}
private final ScheduledExecutorService scheduler =
        Executors.newScheduledThreadPool(1);

public int doMathForAMinute() {
    final Runnable math = new Runnable() {
        public void run() {
            myNr++;
        }
    };
    final ScheduledFuture<?> mathHandle =
            scheduler.scheduleAtFixedRate(math, 10, 10, SECONDS);
    scheduler.schedule(
            new Runnable() {
                public void run() {
                    mathHandle.cancel(true);
                }
            }, 60, SECONDS);
    return myNr;
}

}

and in my main activity and i want it after 1 minute to change my txtview text into 11;

WorkingWithTimeActivity test = new WorkingWithTimeActivity(5);
txtview.setText(String.valueOf(test.doMathForAMinute()));
Was it helpful?

Solution

You should use Callable which can return value rather than Runnable

The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.

public class ScheduledPrinter implements Callable<String> {
    public String call() throws Exception {
        return "somethhing";
    }
}

Then use it like below

    ScheduledExecutorService scheduler = Executors
            .newScheduledThreadPool(1);
    ScheduledFuture<String> future = scheduler.schedule(
            new ScheduledPrinter(), 10, TimeUnit.SECONDS);
    System.out.println(future.get());

This is one shot schedule so it will execute only one time you will need to schedule it again once the get call is returned.


However in your case it will be easy to use a simple AtomicInteger and call addAndGet compare the returned value once your condition arrive cancel the scheduling by calling cancel.

OTHER TIPS

If you want to return the result from doMathForAMinute, then you need not ScheduledExecutorService at all. Just make a loop which runs calculation and then Thread.sleep(). The whole idea of using ScheduledExecutorService is to free the thread which starts the task from waiting the result, but here you are not going to free it.

If, as I suspect, the thread which calls doMathForAMinute is the GUI thread, then it is totally wrong, as your gui would stuck and do not respond for a minute. Instead, doMathForAMinute should only start parallel calculations and the parallel task should itself update UI using runOnUiThread or some other way.

See also:

Android: runOnUiThread does not always choose the right thread?

Where do I create and use ScheduledThreadPoolExecutor, TimerTask, or Handler?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top