我有一个Java任务队列,这个队列在数据库表中。
我需要:
- 每个任务仅使用1个线程
- 同时运行的线程不超过N个。这是因为线程需要与数据库交互,我不希望打开大量的数据库连接。
我认为我可以这样做:
final Semaphore semaphore = new Semaphore(N);
while (isOnJob) {
List<JobTask> tasks = getJobTasks();
if (!tasks.isEmpty()) {
final CountDownLatch cdl = new CountDownLatch(tasks.size());
for (final JobTask task : tasks) {
Thread tr = new Thread(new Runnable() {
@Override
public void run() {
semaphore.acquire();
task.doWork();
semaphore.release();
cdl.countDown();
}
});
}
cdl.await();
}
}
我知道存在ExecutorService类,但不确定能否用它来完成此任务。
那么,你认为这是最好的解决方法吗?或者你能否解释一下ExecutorService如何工作以解决这个问题?
最终解决方案:
我认为最好的解决方案是:
while (isOnJob) {
ExecutorService executor = Executors.newFixedThreadPool(N);
List<JobTask> tasks = getJobTasks();
if (!tasks.isEmpty()) {
for (final JobTask task : tasks) {
executor.submit(new Runnable() {
@Override
public void run() {
task.doWork();
}
});
}
}
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);
}
非常感谢您的回答。顺便说一下,我正在使用连接池,但是与数据库的查询非常繁重,我不希望同时有不受控制的任务数量。