我想创建一个作业队列来执行多个任务。但是,我的要求是我应该能够随时将任务添加到该作业队列中,并且所有这些任务都应该按顺序执行。我在网上搜索了一些解决方案,找到了这两个链接:
但是我不能同时使用这两种解决方案。因为启动
ExecutorService
后我无法向服务添加新任务。因为我们知道它可能会抛出 InterruptedException
或 ConcurrentModificationException
。
您可以使用
BlockingQueue
在单独的线程中继续等待,直到出现一个或多个 Runnable
。
public class Mainer {
private static final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(15);
public static void main(String[] args) {
Thread t = new Thread(() -> {
while (true) {
try {
queue.take().run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
for (int i = 0; i < 10; i++) {
queue.add(() -> {
System.out.println("Hello");
});
}
}
}
我认为您应该使用
ExecutorService
。
submit
方法随时添加新任务。如果您希望
ExecutorService
始终一次运行一个任务,请确保指定最大大小为一个线程的线程池。
请提供一些示例链接
javadocs 有示例。
您提出的反对意见均基于不正确的信息。
- 但是我不能同时使用这两种解决方案。因为启动后
我无法向服务添加新任务。ExecutorService
是的,你可以。这就是
ExecutorService.submit(...)
的作用。
- 因为我们知道它可能会抛出
...InterruptedException
仅当您的应用程序执行某些操作导致发生这种情况时,它才会抛出
InterruptedException
;例如使用 ExecutorService
关闭 shutdownNow()
。 (如果您不想这样做,可以使用 shutdown()
代替,或者根本不关闭执行器。有关更多详细信息,请参阅 javadocs。)
无论如何,您的代码可以处理异常,就像其他答案中的代码一样......尽管它以您不应该在生产代码中执行的方式处理异常。 (将堆栈跟踪打印到标准输出是一个坏主意。在某些情况下,忽略
InterruptedException
可能是错误的事情。)
- ... 或
.ConcurrentModificationException
AFAIK,
ExecutorService
可能抛出 ConcurrentModificationException
的唯一情况是,如果您使用未正确实现的自定义 Queue
类。
将实施添加到Stephen回答
public class MyController {
ExecutorService executor = Executors.newSingleThreadExecutor();
Logger logger = Logger.getLogger(MyController.class.getName());
//POST
public void addTask(String taskId){
Runnable task = createTask(taskId);
executor.submit(task);
}
public void shutdown(){
executor.shutdown();
}
private Runnable createTask(String taskId) {
return new Runnable() {
@Override
public void run() {
try {
taskId.toString();
//your task
}catch (Exception e){
logger.log(Level.SEVERE,"error executing task"+taskId);
}
}
};
}
}