• 比较分析线程池中execute与submit方法的差异


    前言

    Java中异步处理任务时,我们通常都会定义线程池来执行任务。然而执行的方式通常主要有两种:

    1.直接调用execute方法。

    2.调用submit方法,再用Future去get获取执行结果。

    这两种方法分别有怎样的区别呢?

    分析

    我们翻阅Jdk源码则可发现在Executer类中已有定义execute方法如下:

    1. public interface Executor {
    2. /**
    3. * Executes the given command at some time in the future. The command
    4. * may execute in a new thread, in a pooled thread, or in the calling
    5. * thread, at the discretion of the {@code Executor} implementation.
    6. *
    7. * @param command the runnable task
    8. * @throws RejectedExecutionException if this task cannot be
    9. * accepted for execution
    10. * @throws NullPointerException if command is null
    11. */
    12. void execute(Runnable command);
    13. }

    即execute方法可以支持实现了Runnable接口的任务。而我们常用的ExecutorService与Executer的为继承关系。

     从上图信息可以看出ExecutorService中定义submit方法的时候通过重载的方式实现了三个方法,分别可以看出来支持实现了Callable接口的任务、支持实现了Runnable接口的任务。再看关于submit方法定义的描述信息:

    1. /**
    2. * Submits a value-returning task for execution and returns a
    3. * Future representing the pending results of the task. The
    4. * Future's {@code get} method will return the task's result upon
    5. * successful completion.
    6. *
    7. * <p>
    8. * If you would like to immediately block waiting
    9. * for a task, you can use constructions of the form
    10. * {@code result = exec.submit(aCallable).get();}
    11. *
    12. * <p>Note: The {@link Executors} class includes a set of methods
    13. * that can convert some other common closure-like objects,
    14. * for example, {@link java.security.PrivilegedAction} to
    15. * {@link Callable} form so they can be submitted.
    16. *
    17. * @param task the task to submit
    18. * @param <T> the type of the task's result
    19. * @return a Future representing pending completion of the task
    20. * @throws RejectedExecutionException if the task cannot be
    21. * scheduled for execution
    22. * @throws NullPointerException if the task is null
    23. */
    24. <T> Future<T> submit(Callable<T> task);
    25. /**
    26. * Submits a Runnable task for execution and returns a Future
    27. * representing that task. The Future's {@code get} method will
    28. * return the given result upon successful completion.
    29. *
    30. * @param task the task to submit
    31. * @param result the result to return
    32. * @param <T> the type of the result
    33. * @return a Future representing pending completion of the task
    34. * @throws RejectedExecutionException if the task cannot be
    35. * scheduled for execution
    36. * @throws NullPointerException if the task is null
    37. */
    38. <T> Future<T> submit(Runnable task, T result);
    39. /**
    40. * Submits a Runnable task for execution and returns a Future
    41. * representing that task. The Future's {@code get} method will
    42. * return {@code null} upon <em>successful</em> completion.
    43. *
    44. * @param task the task to submit
    45. * @return a Future representing pending completion of the task
    46. * @throws RejectedExecutionException if the task cannot be
    47. * scheduled for execution
    48. * @throws NullPointerException if the task is null
    49. */
    50. Future<?> submit(Runnable task);

    结论

    但从上面两端源码关于方法的注释上即可得出如下的结论。

    1.从支持方面来分析,execute()只能执行实现Runnable接口类型的任务;而submit()不仅可以执实现Runnable类型接口的任务,也可以执行实现Callable接口类型的任务。

    2.从返回结果来分析,execute()没有返回值,而submit()有在添加Callable类型任务的时候有返回值,我们一般通过返回值查看线程执行情况。这样以来,execute更多的是应用于不关注结果的异步执行场景,而submit则倾向于异步计算任务的场景。

    3.从异常处理来分析,submit可以通过Future.get()方法抛出异常,方便我们自定义异常处理;而execute()会终止异常,没有返回值。

  • 相关阅读:
    【20221103】【每日一题】二叉搜索树中的众数
    在UnityUI中绘制线状统计图
    处理机调度
    云计算实战应用案例精讲-【概念篇】多模态(附实战应用案例)
    Redis使用ZSET实现消息队列使用总结一
    GM/T 0005《随机性检测规范》2012版和2021版对比
    微软Win10最新补丁KB5017380更新了什么?
    .NET周刊【12月第1期 2023-12-06】
    Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单
    原生js拖拽滑动条
  • 原文地址:https://blog.csdn.net/sinat_34206747/article/details/125567284