• 【并发编程】- 线程池执行Callable任务获取返回值


    Callable、Future使用

    针对线程Thread对象不具有返回值的功能,但是有请求需要线程返回值,所以需要用到Callable和Future来让线程具有返回值的功能。
    Callable接口与线程密不可分,但是和Runnable有以下主要的区别是

    Callable接口的call()方法可以有返回值,而Runnable接口的run()方法没有返回值。

    Callable接口的call()方法可以声明抛出异常,而Runnable接口的run()方法不可以声明抛出异常。
    执行完Callable接口中的任务后,返回值是通过Future接口进行获取。

    ThreadPoolExecutor使用submit提交Callable的任务

    线程执行代码如下:

    1. public class TheCallable implements Callable<String> {
    2. private int number;
    3. public TheCallable(int number){
    4. super();
    5. this.number=number;
    6. }
    7. @Override
    8. public String call() throws Exception {
    9. Thread.sleep(5000);
    10. return "返回值:"+number;
    11. }
    12. }

    运行类代码如下:

    1. @Slf4j
    2. public class CallableRun {
    3. public static void main(String[] args) {
    4. TheCallable theCallable = new TheCallable(18);
    5. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
    6. Future<String> future = threadPoolExecutor.submit(theCallable);
    7. try {
    8. log.info("开始时间:{}",System.currentTimeMillis());
    9. log.info("线程 "+future.get());
    10. log.info("结束时间:{}",System.currentTimeMillis());
    11. } catch (InterruptedException e) {
    12. e.printStackTrace();
    13. } catch (ExecutionException e) {
    14. e.printStackTrace();
    15. }
    16. }
    17. }

    运行结果如下:

    17:09:57.944 [main] INFO com.ozx.concurrentprogram.executor.controller.CallableRun - 开始时间:1659344997940
    17:10:02.942 [main] INFO com.ozx.concurrentprogram.executor.controller.CallableRun - 线程 返回值:18
    17:10:02.943 [main] INFO com.ozx.concurrentprogram.executor.controller.CallableRun - 结束时间:1659345002943

    从运行结果看出future调用get()是阻塞的,get()方法具有阻塞特性。
    ExecutorService使用submit提交Runnable任务
    方法submit()可以传入Callable对象,也可以传入Runnable对象,说明submit()方法支持有返回值和无返回值的功能。
    运行类代码如下:

    1. @Slf4j
    2. public class RunnableRun {
    3. public static void main(String[] args) {
    4. Runnable runnable = new Runnable() {
    5. @Override
    6. public void run() {
    7. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
    8. log.info("Runnable 输出的内容:{}",simpleDateFormat.format(new Date()));
    9. }
    10. };
    11. ExecutorService executorService = Executors.newCachedThreadPool();
    12. Future future = executorService.submit(runnable);
    13. try {
    14. log.info("任务返回值:{},执行isDone方法结果:{}",future.get(),future.isDone());
    15. } catch (InterruptedException e) {
    16. e.printStackTrace();
    17. } catch (ExecutionException e) {
    18. e.printStackTrace();
    19. }
    20. }
    21. }

    运行结果如下:

    17:31:37.704 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.controller.RunnableRun - Runnable 输出的内容:17:31:37
    17:31:37.715 [main] INFO com.ozx.concurrentprogram.executor.controller.RunnableRun - 任务返回值:null,执行isDone方法结果:true

    从运行结果看出submit()方法传入Callable接口则有返回值,但是传入Runnable则无返回值,执行任务的返回值为null,之前验证过方法get()是具有阻塞特性,而isDone()方法是无阻塞特性。

  • 相关阅读:
    SpringBoot 3.0 来啦!
    【Java分享客栈】一文搞定CompletableFuture并行处理,成倍缩短查询时间。
    第五章:最新版零基础学习 PYTHON 教程—Python 字符串操作指南(第十节 Python——查找字符串中所有重复的字符)
    如何选择合适的官文转录供应商
    【CAS:2306109-91-9 |胺-PEG4-脱硫生物素】价格
    2024 再战基金
    面试系列Spring:Spring的事务传播
    垃圾回收机制的算法实现——增量式垃圾回收算法
    QGC 中添加海康威视摄像头记录(Qt For Android 使用 JNI 进行JAVA 与 C++ 的通讯)
    「深入理解」缓存更新策略及缓存不一致问题解决方案
  • 原文地址:https://blog.csdn.net/LBWNB_Java/article/details/126240999