I'm working on a program that needs to inspect multiple resources in parallel and periodically:
public class JobRunner {
private final SensorService sensorService;
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
public void run() {
sensorService.finalAll().forEach(sensor -> {
Runnable task = () -> {
// read and save new data to log
List<Double> data = sensor.fetchNewData();
this.save(data);
};
// execute every 10 sec
executor.scheduleWithFixedDelay(task, 0, 10, TimeUnit.SECONDS);
});
}
public void save(List<Double> data) {
// ...
}
}
The findAll
call returns a list of about 50 sensors, but when I run the program I see that while all sensors are queried on the first period, only 2-3 are called on subsequent executions (e.g - at 20 sec, 30 sec, etc). I'm thinking that since some sensors return faster than others, they complete the task's waiting cycle earlier and are grabbed by the next thread in the pool, thereby starving the other tasks that are slower to finish.
How can I ensure all tasks (sensors) are given equal treatment? What's are some best practices here; should I use a job queue or a different concurrency mechanism? Thanks.