如何获取子线程的执行结果

VS2019+CAXACAD2023二次开发教程(一、环境搭建) CAXACAD2023的二次开发相关文件和库都在的文件夹下。CAXACAD2023的默认开发环境是VS2019,如果是用VS2019的环境话,可以直接安装这个插件,安装好后就可以一键新建的项目,新建的项目会自动帮我们配置好所有的环境,并且生成必要的代码和初始的框架。(本来想用VS2022的,但配置环境太麻烦,用VS2022,增加一个环境变量是可以运行自带的例程的,但新建项目要配置的东西和环境太多,就放弃折腾了) 阅读详情

一 概述

对于线程的管理,我们不仅可以通过线程池进行管理,我们还可以通过Future和Callable进行管理。

二 Runnable的缺陷

Runnable接口无法返回一个值返回。

Runnable接口源码

@FunctionalInterface
public interface Runnable {
    //void方法,不存在返回值
    public abstract void run();
}

Runnable接口不能抛出checked Exception。

三 Callable接口

Callable接口源码

@FunctionalInterface
public interface Callable<V> {
    //返回值为泛型V,可抛出异常
    V call() throws Exception;
}

四 Future接口

Future接口的核心思想是,处理一个方法非常耗时,系统没有必要阻塞在这个方法上等方法的返回,这时候我们可以让子线程来处理这个耗时的方法,当子线程在处理这个耗时的方法是,系统可以通过主线程去处理其他任务,同时可以利用Future类控制方法的返回或取消方法的执行。

Future接口源码

public interface Future<V> {
    /**
     *取消任务的执行,mayInterruptIfRunning表示是否中断正在执行的任务
     *情况一:如果这个任务还没开始执行,那么这种情况最简单,任务回被正常的取消,未来也不会被执行 
             并返回true
     *情况二:如果任务已经完成,或者已经取消,那么cancel()方法会执行失败,方法返回false
     *情况三:如果这个任务已经开始执行,此时这个取消方法将不会直接取消这个任务,而是会根据我们所 
             填的参数mayInterruptIfRunning做判断。
             传入false时,对已经执行的任务时没有影响,而那些未开始执行的任务只会被标记,在以后它
             执行的时候应该也不会执行。
             传入true时,会正常去尝试执行中断。*/
    boolean cancel(boolean mayInterruptIfRunning);
  
    //判断任务是否执行完毕,执行完毕并不代表任务被成功执行(包括中断和取消)
    boolean isDone();
    
    /**
     *获取任务的返回结果
     *情况一:任务正常完成,get方法会立即返回结果。
     *情况二:任务尚未完成(任务未开始或者进行中),get将阻塞并直到任务完成。
     *情况三:任务执行过程中抛出异常,get方法抛出ExecutionException,是由call()方法产生的异常,
             不管call()执行时抛出任务异常,get方法都只是抛出ExecutionException异常。
     *情况四:任务被取消并抛出CancellationException。
     *情况五:任务超时抛出TimeoutException。
     **/
    V get() throws InterruptedException, ExecutionException;
    
    //限时获取任务的返回结果
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

Future.cancle(true)和Future.cancle(false)所适用的情况

Future.cancle(true)

  1. 适用于能够处理interrupt的任务。

Future.cancle(false)仅用于避免启动尚未启动的任务

  1. 未能处理interrupt的任务
  2. 不清楚任务是否支持取消
  3. 需要等待已经开始的任务执行完成。

Callable接口与Future类的关系

我们可以通过Future接口的get()方法获取Callable接口的返回结果,通过get(time)方法限时获取Callable接口的返回结果,通过Future.isDone()方法来判断任务是否已经执行完了,还可以通过cancel()方法将任务取消。

在子线程的call()方法未执行完毕之前,主线程调用get()方法时会被阻塞,直到call()方法返回结果后,主线程才能够通过Future.get()方法得到结果,然后主线程由阻塞状态切换到可执行状态。

Future接口是一个存储器,它存储了任务执行call()返回的结果,而这个任务的执行时间完全取决于call()方法执行的情况而无法提前确定器执行的时间。

线程池的submit方法返回Future对象源码

public interface ExecutorService extends Executor {
    //submit方法会被立即提交且会立即将返回结果返回
    <T> Future<T> submit(Callable<T> task);

    <T> Future<T> submit(Runnable task, T result);

    Future<?> submit(Runnable task);
}

线程池提交了任务之后,提交时线程池会立即返回给我们一个空的Future容器。当线程的任务一旦执行完毕,即我们可以获取结果的时候,线程池便会把该结果放到之前给我们的那个空的Future容器中,并不需要重新创建,所以我们便可以从该容器中获得任务执行的结果。

Future的注意点

  1. 当for循环批量获取Future的结果时,容易发生一部分线程很慢的情况,get方法调用时应使用timeout限制。
  2. Future的生命周期只能前进不能后退。如同线程池的生命周期一样,一旦完全完成了任务,他就会永久停在"已完成"的状态,不能重头再来。

五 FutureTask

我们可以用FutureTask来获取Future和任务的结果,它是一种包装器,可以将Callable转化成Future和Runnable,因为它同时实现了Future接口和Runnable接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable接口的返回值。

    

FutureTask源码

public class FutureTask<V> implements RunnableFuture<V> {
     public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

      public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

    public V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (unit == null)
            throw new NullPointerException();
        int s = state;
        if (s <= COMPLETING &&
            (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
            throw new TimeoutException();
        return report(s);
    }
}

FutureTask创建Future实例代码

public class FutureTaskDemo {

    public static void main(String[] args) {
        Task task = new Task();
        FutureTask<Integer> integerFutureTask = new FutureTask<>(task);
        //利用线程的方法
        //new Thread(integerFutureTask).start();
        //线程池方法
        ExecutorService service = Executors.newCachedThreadPool();
        service.submit(integerFutureTask);
        try {
            System.out.println("task运行结果:"+integerFutureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

class Task implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        System.out.println("子线程正在计算");
        Thread.sleep(3000);
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            sum += i;
        }
        return sum;
    }
}

由源码与实例代码可知,可以将Callable实例作为参数,生成FutureTask的对象,然后将这个对象当作要给Runnable对象,用线程池或其他线程执行这个Runnable对象,最后通过FutureTask获取刚才执行的结果。

开关电源三大基本拓扑:反激、正激与桥式选型本质 开关电源拓扑是电力电子系统设计的核心基础概念,其本质决定能量传递路径、器件应力分布与系统物理边界。反激拓扑以耦合电感形式实现隔离与升降压,适用于小功率AC-DC场景;正激拓扑依赖实时能量传递与强制复位机制,支撑中功率高效率需求;桥式拓扑(含推挽/半桥/全桥)通过电压应力分摊与双向磁化,成为大功率系统的刚性选择。理解三者在磁芯工作模式、电流连续性、直流偏磁抑制等方面的原理差异,直接关系到效率、温升、EMI及可靠性等关键技术指标。本文聚焦反激、正激、桥式三大工程级基本拓扑的物理本质与落地约束,揭示从需求参数到电 阅读详情

相关推荐

深度学习环境搭建:CUDA、Anaconda、PyTorch 完整安装与验证教程

步骤操作验证命令1安装 CUDA 工具包nvcc -V2安装 Anaconda3创建 yolo 环境4安装 PyTorch5验证 GPU。

qq_37606844的博客 319

java高并发系列 - 第31天:获取线程执行结果,这6种方法你都知道?

结合这个需求,我们使用,来对之前学过的知识点做一个回顾,加深记忆。

GitHub质检员 1617

Isaac Sim 使用经验(配置要求,云服务器)

Google Colab及AutoDL都是在docker内运行,其中google colab并不支持docker指令,而依照AutoDL的相关文档,AutoDL并不直接提供docker指令。2. Google Colab/AutoDL 不支持图形化界面,图形渲染等任务,所以没有办法使用Omniverse Streaming进行直播,从而更好的对结果进行展示。对于第一点,或许存在直接手动复现镜像的可能,但是考虑到Isaac Sim/Isaac Lab由于比较新,可能不够稳定,因此还是按照官方文档进行部署。

weixin_44211433的博客 4587

获取子线程执行结果

Callable 类似于Runnable,被其他线程执行的任务 实现call方法 有返回值 Future Callable和Future的关系我们可以用Future.get来获取Callable接口返回的执行结果还可以通过Future.isDone()来判断任务是否已经执行完了,以及取消这个任务,限时获取任务的结果等。 在call()未执行完毕之前,调用get()的线程(假定此时是主线程)会被阻塞,直到call()方法返回了结果后,此时future.get()才会得到该结果,然后主线程才会切换到run

yeguangchen的博客 820

【开关电源篇】开关电源——只需这三个阶段,从电源小白到维修大神

🔌 该篇为的原创文章跳转目录,小二持续更新跳转链接,尽情关注!

2301_81299416的博客 2387

深度学习Halcon中GPU显存利用率高,但GPU、CPU利用率较低,导致模型训练速度很慢,通过设置硬件参数的解决方法

深度学习Halcon中GPU显存利用率高,但GPU、CPU利用率较低,导致模型训练速度很慢,通过设置硬件参数的解决方法 前言 在训练自己模型的时候,会遇到GPU显存利用率高,但GPU、CPU利用率较低,导致模型训练速度很慢的问题。这个问题一方面是由于硬件没有设置到最佳工作状态,另一方面是代码中参数没有设置好。最近在跑Halcon DL遇到这个问题,而Halcon不像开源的几个框架那样自由,代码封装的比较多。所以遇到这种问题,只能在参数最优的情况下,通过设置硬件参数来提升性能。 当然,在跑DL之前,无论什么框

ZiLiangQin的博客 9914

获取子线程的执行结果

创建线程有哪几种方式 继承Thread类(Thread类也是实现Runnable接口); public class Thread implements Runnable { 实现Runnable接口; 通过线程池创建线程池; 实现Callable接口与ExecutorService结合使用 因为Java的类是单继承,接口可以多实现。所以在创建子任务的时候,更多的是选择实现接口。线程池的出...

ycd500756的博客 915

瑞芯微RK3506开发板DSM音频开发避坑指南:从硬件改接到内核配置全流程

本文详细解析了在瑞芯微RK3506开发板上进行DSM音频开发的完整流程与关键避坑点。内容涵盖从硬件改造(如电阻焊接)、内核驱动配置(DTS参数、补丁应用)到系统调试与波形分析的全过程,旨在帮助嵌入式开发者高效实现高信噪比、低成本的音频方案,避免常见错误。

weixin_29164091的博客 407

Future - 获取子线程执行结果

1. 为什么要Future机制 对比常见的两种创建线程的方式,一种是直接继承Thread,另外一种就是实现Runnable接口,他们在执行完任务之后无法获取执行结果,从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果 Future模式的核心思想是能够让主线程将原来需要同步等待的这段时间用来做其他的事情。(因为可以异步获得执行结果,所以不用...

Javaer`s blog 1578

嵌入式Linux Qt/QML开发实战:从Buildroot配置到应用部署

本文详细介绍了嵌入式Linux Qt/QML开发全流程,从Buildroot系统配置、交叉编译工具链搭建到应用部署与调试。以RK3506开发板为例,提供实战指南,帮助开发者高效完成嵌入式应用开发,解决常见环境配置与性能优化问题。

m2n3o4p5的博客 224

Waymo数据集里的隐藏彩蛋:5个激光雷达数据融合实战(附Python代码)

本文深入解析Waymo数据集中5个激光雷达的数据融合技术,提供Python实战代码,帮助开发者掌握多传感器协同工作的关键方法。通过时间同步、坐标转换和运动补偿等技术,实现高精度3D场景重建,提升自动驾驶系统的环境感知能力。

weixin_30399821的博客 79

java计算所有子线程结果_如何获取子线程的执行结果

前言博主以前面试的时候,真真切切的被问过这样一道题:如何获取子线程的执行结果?总所周知,在单线程情况下,想获取线程执行结果很简单,只需要写类似的代码即可:Object result = xxx.getXxx();但是在多线程的情况下,想要获取子线程的执行结果,恐怕就没这么简单了。剑走偏锋我们都知道开启一个新线程的方式有两种:继承Thread类、实现Runnable接口。可是这两种方式都没有返回值,...

weixin_33232907的博客 557

51单片机STC8G1K08驱动ws2812记录

使用51单片机控制17个2812灯,这里选择STC8芯片,最大频率可以达到35M,参考网上的各种文章案例,使用定时器做的时候实测做不到规格书要求的245-345ns,STC8G1K08不带PWM,所以只能使用nop来做,好在单片机在这里只有做编程灯的功能,省略测试过程,下面是程序,使用的是24MHz内部晶振 //设置一个灯珠 void SendOnePix(unsigned char *ptr) { unsigned char i,j; unsigned char temp; fo...

的博客 7320

Future获取子线程的执行结果

获取子线程的执行结果 future和Callable Runnable的缺陷 @FunctionalInterface public interface Runnable { public abstract void run(); } 不能返回一个返回值 不能抛出checked Exception Callable接口 类似于Runnable,被其他线程执行的任务 实现call方法,有返回值 @FunctionalInterface public interface Callable&lt

u010497615的博客 1732

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

JUC之获取子线程的执行结果Future和Callable

Runable的缺点:没有返回值也不能抛出Checked Exception Future的主要方法 get() //get方法的行为取决于Callable任务的状态分五种情况 //1 任务正常完成,get立即返回结果 //2 任务尚未完成(未开始或进行中),get被阻塞直到任务完成 //3 任务被中断,get返回InterruptedException //4 任务被取消,get返回CancellationException //5 任务执行异常,get返回ExecutionExcepti

MineCodelife的博客 239

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

[Java并发与多线程](二十一)获取子线程的执行结果(*)【来而不往非礼也】

Future和Callable——治理线程的第二大法宝1、Runnable的缺陷2、Callable接口3、Future类3.1、Future的主要方法:5个3.2、Future用法3.2.1 用法1:线程池的submit方法返回Future对象3.2.1.1 get的基本用法3.2.1.2 Callable的Lambda表达式形式3.2.1.3 多个任务,用Future数组来获取结果3.2.1.4 任务执行过程中抛出Exception和isDone展示3.2.1.5 获取任务超时3.2.2 用法2:用Fu

xujunson的博客 734

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

六十九、Qt之开启子线程执行业务,并使用“自定义事件”获取子线程结果实例

一、概况 1.自定义事件 class AlgRunnable; class ExcutedEvent : public QEvent { public: ExcutedEvent(AlgRunnable *r) : QEvent(evType()), m_runnable(r) { } AlgRunnable *m_runnable; static QEvent::Type evType() { if (s_

panchang199266的博客 677

【多线程】主线程等待子线程执行完毕在执行并获取执行结果的方式记录(有注解代码无坑)

适配小白,解释详细

Wan_Yuan的博客 448

《架构风清扬-Java面试系列第22讲》如何获取子线程的执行结果

如何获取子线程的执行结果?直接上代码,逐行代码解析!

架构风清扬 321

java 获取子线程_Java 主线程获取子线程返回结果

1.自定义package com.jgyang.com;public class MySyncThreadTest {public static void main(String[] args) throws Exception {CustomRunnable cRunnacle = new CustomRunnable();Thread thread = new Thread(cRunnacle...

weixin_39547596的博客 1353

java中 等待所有子线程结束 后再执行一段代码。

今天有一个需求是:在一个方法中开启了一个子线程来执行操作,返回值依赖于子线程的执行结果,这样如果要返回正确的值,就需要开启子线程后 主线程等待子线程,然后子线程执行结束后,主线程再继续执行。 主线程等待子线程需要用到:CountDownLatch 代码如下: import java.util.concurrent.CountDownLatch; public class Cou

zwcwu31的专栏 3624

Future异步执行

前言 随着业务的发展,系统的功能也越来越多,这时候很多业务操作就需要异步执行,提高效率。大多时候,我们都可以采用线程池来实现异步执行的需求,但是,有时候主流程需要等待其他任务执行完以后才能继续执行,又或者是主流程需要知道其他任务执行的结果,这时候,就需要采用线程的合并了。 在讲线程合并之前,我们先来看看平时使用Thread是怎么实现主线程等待其他线程的。 join合并线程 当一个线程需要等待其他线程执行完再继续执行的时候,我们可以使用join或者是CountDownLatch,这里只说join,CountD

pipi蛋 815

Java多线程:获取子线程结果的5种方法

在 Java 多线程编程中,获取子线程执行结果的方法丰富多样,每种方法都有其适用场景和特点。Thread.join () 方法简单直接,适用于需要主线程等待单个子线程执行完毕的场景,但获取结果的方式较为间接。Callable 和 Future 接口以及 FutureTask 类提供了更直接获取子线程返回值的能力,并且支持对任务的更多控制。CompletableFuture 类则在异步编程方面表现得更为强大,不仅能获取结果,还能方便地进行任务组合和回调处理,非常适合复杂的异步任务场景。

2501_93873871的博客 610

主线程等待子线程结束

主线程怎样等待所有子线程执行完?子线程怎样获得子线程的运行结果? 直接贴代码了: package com.ly.demo.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; /**  * 线程类  * 可以实现Ru

最初的梦想 695

Java 主线程获取子线程返回结果

package yangtest.com.jgyang.com; public class MySyncThreadTest { public static void main(String[] args) throws Exception { CustomRunnable cRunnacle = new CustomRunnable(); Thread...

u010980938的专栏 6458

android 线程返回参数,子线程获取返回值问题

String string = "3";//int i = getString(string);//Log.d(TAG, "ExampleUnitTest.synaized." + i);}public int getString(String s) {final int[] i = {0};Observable.just(s).map(new Function() {@Overridepubl...

weixin_36246453的博客 1792
上一篇: Java中的不变性(Immutable)和final有关吗
下一篇: 我操作Linux系统的一些命令
至学者
博客等级 码龄9年 180粉丝 773原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值