Search code examples
javaconcurrencyscheduled-tasksschedulingjava.util.concurrent

Get result of scheduled task


I am trying to learn the java concurrency API, and for my exercise i want to schedule a job to run periodically every X seconds. The job will compute a random number.

I want to get the result of the scheduled task as soon as it is finished. I could not get this done only with the API so i hacked it.

Is there a way to do this better, without using low level mechanisms? I would like to be able to remove the synchronization in MyRandomGiverTask.getResult() and instead use something like the ScheduledFuture.get(). But in my code ScheduledFuture is never done/completed. This is my current solution:

class A {
    public static void main() {
        MyRandomGiverTask task = new MyRandomGiverTask(200);
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        ScheduledFuture<Double> scheduledDouble =
            (ScheduledFuture<Double>) scheduler
                .scheduleAtFixedRate(task, 1, 4, TimeUnit.SECONDS);
        while (true) {
            System.out.println(" >> " + task.getResult());
        }
    }
    public class MyRandomGiverTask implements Runnable {
        MyRandomGiver giver = new MyRandomGiver();
        int param;
        double result;
        public MyRandomGiverTask(int param) { this.param = param; }
        @Override public void run() { result = giver.getRandom(param); }
        public double getResult() {
            try {
                while (result == 0d) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                return result;
            } finally {
                result = 0d;
            }
        }
    }
}

Solution

  • If you want to get every random number computed, use a BlockingQueue. the scheduled tasks put()s new random numbers in the queue and whatever wants them can take() them.

    also, if you were going to use something like your solution, you would want to use wait()/notify(), not sleep().