What is the best approach to scheduling Callables that can time out in a polling situation?
I have several Callables that ask for some JMX Beans so everyone can disconnect. I want a poll for the values to let you speak every second. The most naive approach is to start each on a separate thread, but I want to keep the number of threads to a minimum. What options do I need to do better?
a source to share
My interpretation is that you have a bunch of callables that need to be polled at some interval. The problem with thread pooling is that the pool will get polluted by the slowest members and your faster ones will starve.
It looks like you have scheduling control, so you might want to consider the exponential deferral method. That is, after Callable X starts (and possibly times out), you wait 2 seconds instead of 1 second before rescheduling it. If still fails, go to 4s, then 8s, etc. If you are using ScheduledThreadPoolExecutor , it comes with a built-in way to do this, which allows you to schedule execution after a set delay.
If you set a constant timeout, this strategy will reduce your susceptibility to slow monopolization of your pool. It is very difficult to get rid of this problem completely. Using a separate thread for each requested object is really the only way to make sure you don't get hungry, and it can be very resource intensive as you say.
Another strategy is to add your pool to fast and slow. If the object is disabled (for example more than N times), you move it to the slow pool. This speeds up your fast pool, and while the slow ones all infiltrate each other, at least they don't clog the fast pool. If they have good stats for a while, you can submit them to the fast pool again.
a source to share
Once you submit
a Callable
, you get a Future
- descriptor of the future result. You can wait for it to complete in a certain amount of time:
Future<String> future = executorService.submit(callable);
try {
future.get(1, TimeUnit.SECONDS);
} catch ( TimeoutException e ) {
future.cancel(true);
} catch ...
Calling get with a timeout allows you to get an exception if the task has not been completed. It does not distinguish between tasks not started and does not start, but does not complete. On the other hand, it cancel
will accept a boolean parameter mayStopIfRunning
so that you can choose, for example. only cancel scheduled tasks.
a source to share