我目前有一个类列表,每个类都启动一个这样的调度程序:
private ScheduledFuture<?> myTask;
private ScheduledExecutorService scheduler;
public startScheduler() {
scheduler = Executors.newScheduledThreadPool( 1 );
myTask = scheduler.scheduleAtFixedRate(new Runnable() {
// doing work here
},
delay,
interval,
TimeUnit.MILLISECONDS );
}
所以每个类基本上都启动它自己的调度程序,只有一个任务。但正如我现在所理解的,调度程序可以并行执行和运行更多任务。任务(或我当前的程序中的调度程序)具有不同的延迟和间隔值,并且启动的调度程序的数量对我来说是未知的(因为用户可以启动新的并停止运行的调度程序)。所有调度程序并行运行。那么我应该更改我的代码才能只使用一个调度程序吗?我应该更喜欢“CachedThreadPool”吗?
答案 0 :(得分:1)
是的,您只能使用一个池来安排所有任务。此外,如果您需要按照当前时间间隔安排任务,则应坚持使用newScheduledThreadPool
,因为newCachedThreadPool
仅返回ExecutorService
接口,而不是ScheduledExecutorService
答案 1 :(得分:0)
是的,我建议使用一个调度程序。
Executors.newCachedThreadPool()返回一个ExecutorService,而不是ScheduledExecutorService,所以我认为这不适合你。我坚持使用newScheduledThreadPool()
答案 2 :(得分:0)
我发现不仅对我来说是惊喜:ScheduledThreadPoolExecutor有一个固定的线程池大小:
没有。来自http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html:
....它使用corePoolSize线程作为固定大小的池...
其他一些相关链接:
Why is there no scheduled cached thread pool provided by the Java Executors class?
Why does ScheduledThreadPoolExecutor only accept a fixed number of threads?
看看测试结果:
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
建议的解决方案是:
scheduledExecutor = new ScheduledThreadPoolExecutor(150); //max thread
scheduledExecutor.setKeepAliveTime(10, TimeUnit.SECONDS);
scheduledExecutor.allowCoreThreadTimeOut(true); // allow terminate core idle threads
从示例中可以看出,最大线程池大小不能通过setMaxPoolSize更改,而是通过setCorePoolSize
更改