我正在使用带有newSingleThreadExecutor的 Actuator 服务来按顺序执行我的Runnable任务,但似乎不能保证串行执行顺序,因为某些时候任务是以随机顺序执行的 .
executorService = Executors.newSingleThreadExecutor();
executorService.submit(MyTask1);
executorService.submit(MyTask2);
MyTask执行一些异步操作,并将结果发送回我正在执行任务的类 .
虽然文档说,newSingleThreadExecutor()任务必须连续执行,我无法找到我在这里缺少的东西 . 任何帮助将不胜感激 .
谢谢
2 回答
tl;博士
如果你正在观察的结果是无序的,那么一切都很好 . 异步工作正在各自独立的时间表上完成 . 根据定义,任务#1启动的异步工作可能不会在完成任务#1,2和3之后很久才完成(例如) .
异步意味着“不要等我”
你提到过:
异步执行意味着调用代码不需要等待异步操作完成 .
调用代码,即提交给执行程序服务的任务,使异步工作的请求完成,任务立即继续 . 如果该任务没有进一步的工作,则任务完成 . 因此执行程序服务可以继续 .
执行程序服务继续 . 执行程序服务执行第二个提交的任务 . 同时,上面要求的异步工作可能尚未完成 . 也许异步工作正等待资源等待网络上的调用返回,或者异步工作正在等待数据库查询执行 . 通过definition of asynchronous,不会阻止提交给执行人的任务 . 执行程序服务现在正在运行第二个提交的任务,可能是第三个或第四个,最后,您的异步工作完成 .
功能,而不是错误
换句话说,一个功能,而不是一个bug . Executors.newSingleThreadExecutor()返回的ExecutorService履行了“保证任务顺序执行”的承诺 . 事实上,作为这些任务中的副产品之一,旋转异步工作并不会改变提交的任务确实按顺序执行的事实 .
由于执行顺序保证是顺序的,因此您可能不会在实际运行的代码中使用单个线程执行程序 .
作为一种解决方法,提交一项执行两项任务的任务: