i currently have a list of classes every class starts a scheduler like this:
private ScheduledFuture<?> myTask;
private ScheduledExecutorService scheduler;
public startScheduler() {
scheduler = Executors.newScheduledThreadPool( 1 );
myTask = scheduler.scheduleAtFixedRate(new Runnable() {
// doing work here
},
delay,
interval,
TimeUnit.MILLISECONDS );
}
So every class basically starts it's own scheduler and only has one task. But as i understand now a scheduler can take and run more tasks in parallel. The tasks (or in my current program the schedulers) have different delay and interval values and the number of schedulers started is unknown to me (cause the user can start new ones and stop running ones). All schedulers run in parallel. So should i change my code in order to use only one scheduler? Should I prefer the "CachedThreadPool"?
Yes, you can use just one pool to schedule all your tasks. Also, if you need the ability to schedule tasks at time intervals as you are currently doing, you should stick with newScheduledThreadPool
because newCachedThreadPool
returns only an ExecutorService
interface and not ScheduledExecutorService
.
I see it is surprise not only for me: ScheduledThreadPoolExecutor has a fixed threadpool size:
No. From http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html:
.... it acts as a fixed-sized pool using corePoolSize threads ...
Some other related links:
Why is there no scheduled cached thread pool provided by the Java Executors class?
http://coding.tocea.com/java/dmi_futile_attempt_to_change_maxpool_size_of_scheduled_thread_pool_executor/
Why does ScheduledThreadPoolExecutor only accept a fixed number of threads?
Have a look at test result:
public class AsyncExecutorTest {
private static final ScheduledThreadPoolExecutor SCH_EXECUTOR = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
private static final ExecutorService EXECUTOR = (ExecutorService) Executors.newCachedThreadPool();
public static final int NUMBER = 10;
@Test
public void testSubmit() throws Exception {
submit(EXECUTOR);
submit(SCH_EXECUTOR);
SCH_EXECUTOR.setMaximumPoolSize(100);
submit(SCH_EXECUTOR);
SCH_EXECUTOR.setCorePoolSize(100);
submit(SCH_EXECUTOR);
}
private void submit(ExecutorService exe) throws InterruptedException {
long start = System.currentTimeMillis();
final CountDownLatch cdt = new CountDownLatch(NUMBER);
for (int i = 0; i < NUMBER; i++) {
exe.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
cdt.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
cdt.await();
System.out.println(System.currentTimeMillis() - start);
}
}
1002
5004
5001
1006
Suggested solution is:
scheduledExecutor = new ScheduledThreadPoolExecutor(150); //max thread
scheduledExecutor.setKeepAliveTime(10, TimeUnit.SECONDS);
scheduledExecutor.allowCoreThreadTimeOut(true); // allow terminate core idle threads
From example can be seen that max thread pool size could be changed not by setMaxPoolSize but by setCorePoolSize
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With