首页 文章

ExecutorService按顺序执行runnable

提问于
浏览
1

我正在使用带有newSingleThreadExecutor的 Actuator 服务来按顺序执行我的Runnable任务,但似乎不能保证串行执行顺序,因为某些时候任务是以随机顺序执行的 .

executorService =  Executors.newSingleThreadExecutor();
executorService.submit(MyTask1);
executorService.submit(MyTask2);

MyTask执行一些异步操作,并将结果发送回我正在执行任务的类 .

虽然文档说,newSingleThreadExecutor()任务必须连续执行,我无法找到我在这里缺少的东西 . 任何帮助将不胜感激 .

谢谢

2 回答

  • 3

    tl;博士

    如果你正在观察的结果是无序的,那么一切都很好 . 异步工作正在各自独立的时间表上完成 . 根据定义,任务#1启动的异步工作可能不会在完成任务#1,2和3之后很久才完成(例如) .

    异步意味着“不要等我”

    你提到过:

    MyTask执行一些异步操作

    异步执行意味着调用代码不需要等待异步操作完成 .

    调用代码,即提交给执行程序服务的任务,使异步工作的请求完成,任务立即继续 . 如果该任务没有进一步的工作,则任务完成 . 因此执行程序服务可以继续 .

    执行程序服务继续 . 执行程序服务执行第二个提交的任务 . 同时,上面要求的异步工作可能尚未完成 . 也许异步工作正等待资源等待网络上的调用返回,或者异步工作正在等待数据库查询执行 . 通过definition of asynchronous,不会阻止提交给执行人的任务 . 执行程序服务现在正在运行第二个提交的任务,可能是第三个或第四个,最后,您的异步工作完成 .

    功能,而不是错误

    换句话说,一个功能,而不是一个bug . Executors.newSingleThreadExecutor()返回的ExecutorService履行了“保证任务顺序执行”的承诺 . 事实上,作为这些任务中的副产品之一,旋转异步工作并不会改变提交的任务确实按顺序执行的事实 .

  • 3

    由于执行顺序保证是顺序的,因此您可能不会在实际运行的代码中使用单个线程执行程序 .

    作为一种解决方法,提交一项执行两项任务的任务:

    executorService.submit(() -> {MyTask1.run(); MyTask2.run();});
    

相关问题