12.如何执行批量任务
如何执行批量任务?
如果你想让线程池执行批量任务,那么你可以试试invorkAll或invorkAny方法。
invorkAll
首先来看invorkAll方法,它的作用是执行批量任务,当所有任务完成时,返回future集合,也就是装有执行结果的集合。还有一个参数是将批量任务以集合的形式传递给线程池,集合的泛型是callable类型,说明能批量执行的任务只能是callable任务。
下面动画演示invorkAll方法的执行过程,这是一个正在运行的线程池,
这是我们要执行的批量任务,
要用invorkAll方法提交给线程池,线程池开始处理这些任务,
当所有任务都执行完成
集中反馈这些结果,调用者拿到这些结果以后可自行处理
下面编写实例代码。
首先定义一个任务task,实现callable接口,因为批量任务只能是callable任务,任务结果类型是integer,重写call方法,定义一个int类型的属性index,用于记录任务编号,重载构造方法用于初始化index。这里我们返回index,在返回之前,我们使每个执行任务的线程休眠一秒钟,目的是看看是不是所有任务都执行完,一起返回的结果,至此任务编写完成
接下来我们来批量执行该任务,创建一个task集合,然后通过for循环往集合中装10个任务,接着创建一个固定大小为5的线程池,再接着调用invorkAll方法,并将任务集合传给他。
接收方法返回值,该方法有异常抛出,使用try-catch将其捕获,遍历任务执行结果集合,调用future的get方法,输出任务执行结果,get方法有异常抛出,继续使用catch将其捕获。写上finally代码块,在finally代码块中调用shoudown方法关闭线程池
至此main方法编写完成,整个例子也编写完成。
执行程序观察执行结果,从执行结果来看,程序按顺序输出,1~10
说明invorkAll方法是按顺序执行任务的,也是按顺序返回执行结果的。
接下来来看看超时的invorkAll或invorkAny它们的作用是指定时间内完成任务,完成不了的任务全取消,
参数timeout和unit分别是超时时间和时间单位,
这两个方法除了范围值不同以外,其余的都相同。下面我们就来选择其中的invorkAll来作为演示方法,先看一下它的执行过程。
invorkAll超时
这是一个正在运行的线程池,
这是我们要执行的批量任务。
调用invorkAll方法,将批量任务提交给线程池,线程池开始处理这些任务,
执行时间只有三秒钟,三秒内能完成多少任务,完成多少任务,
时间到了以后未完成的任务全部取消,
将已完成的任务结果全部返回给调用者,调用者拿到任务结果以后可自行处理。
下面编写事例代码,任务代码不变,执行任务的代码还是沿用之前的,只不过我们需要调用超时的invorkAll方法,指定超市时间为一秒钟,
至此事例改写完毕,看看改写后的结果。程序输出1~5,并抛出任务取消异常,
提交了10个任务,只执行完5个,还有5个没执行完,没执行完的任务被取消了,所以就抛出了任务取消异常,
invorkAny
最后来看看invorkAny方法它的作用是执行批量任务,返回最先完成的任务的执行结果,取消未完成的任务,这是它和invorkAll方法的不同之处。
另外参数在前面介绍过的,这里就不再赘述,
下面动画也是 invorkAny方法的执行过程,这是一个正在运行的线程池,
这是我们要提交的批量任务,
调用 invorkAny方法将任务集合提交给线程池,现成池开始处理任务,
当其中有一个任务最先完成时,取消其他未完成的任务,
返回最先完成的任务结果。
下面编写事例代码,任务代码不变,执行任务的代码还是引用之前的,只不过需要将invorkAll方法改为invorkAny方法,并且将超时参数删掉。invorkAny方法直接返回任务执行结果,所以需要将集合改为单个结果。遍历结果的for循环也可以删掉了,输出执行结果也不需要调用get方法的,改为直接输出,这次例子改写完成,
看看改写后的结果。呈现输出 五,
说明第五个任务是最先完成的。
总结
最后总结一下本节内容。本节介绍了执行批量任务的方法invorkAll和invorkAny它们的作用及用法,这里就不再赘述了。在实际开发中偶尔也会用到他们。
附录:
笔记完整文本:
如果你想让线程池执行批量任务,那么你可以试试invorkAll或invorkAny方法。首先来看invorkAll方法,它的作用是执行批量任务,当所有任务完成时,返回future集合,也就是装有执行结果的集合。还有一个参数是将批量任务以集合的形式传递给线程池,集合的泛型是callable类型,说明能批量执行的任务只能是callable任务。下面动画演示invorkAll方法的执行过程,这是一个正在运行的线程池,这是我们要执行的批量任务,要用invorkAll方法提交给线程池,线程池开始处理这些任务,当所有任务都执行完成集中反馈这些结果,调用者拿到这些结果以后可自行处理,下面编写实例代码。 首先定义一个任务task,实现callable接口,因为批量任务只能是callable任务,任务结果类型是integer,重写call方法,定义一个int类型的属性index,用于记录任务编号,重载构造方法用于初始化index。这里我们返回index,在返回之前,我们使每个执行任务的线程休眠一秒钟,目的是看看是不是所有任务都执行完,一起返回的结果,至此任务编写完成,接下来我们来批量执行该任务,创建一个task集合,然后通过for循环往集合中装10个任务,接着创建一个固定大小为5的线程池,再接着调用invorkAll方法,并将任务集合传给他。 接收方法返回值,该方法有异常抛出,使用try-catch将其捕获,遍历任务执行结果集合,调用future的get方法,输出任务执行结果,get方法有异常抛出,继续使用catch将其捕获。写上finally代码块,在finally代码块中调用shoudown方法关闭线程池,至此main方法编写完成,整个例子也编写完成。执行程序观察执行结果,从执行结果来看,程序按顺序输出,1~10说明invorkAll方法是按顺序执行任务的,也是按顺序返回执行结果的。接下来来看看超时的invorkAll或invorkAny它们的作用是指定时间内完成任务,完成不了的任务全取消,参数timeout和unit分别是超时时间和时间单位,这两个方法除了范围值不同以外,其余的都相同。下面我们就来选择其中的invorkAll来作为演示方法,先看一下它的执行过程。 这是一个正在运行的线程池,这是我们要执行的批量任务。调用invorkAll方法,将批量任务提交给线程池,线程池开始处理这些任务,执行时间只有三秒钟,三秒内能完成多少任务,完成多少任务,时间到了以后未完成的任务全部取消,将已完成的任务结果全部返回给调用者,调用者拿到任务结果以后可自行处理。下面编写事例代码,任务代码不变,执行任务的代码还是沿用之前的,只不过我们需要调用超时的invorkAll方法,指定超市时间为一秒钟,至此事例改写完毕,看看改写后的结果。程序输出1~5,并抛出任务取消异常,提交了10个任务,只执行完5个,还有5个没执行完,没执行完的任务被取消了,所以就抛出了任务取消异常,最后来看看invorkAny方法它的作用是执行批量任务,返回最先完成的任务的执行结果,取消未完成的任务,这是它和invorkAll方法的不同之处。 另外参数在前面介绍过的,这里就不再赘述,下面动画也是 invorkAny方法的执行过程,这是一个正在运行的线程池,这是我们要提交的批量任务,调用 invorkAny方法将任务集合提交给线程池,现成池开始处理任务,当其中有一个任务最先完成时,取消其他未完成的任务,返回最先完成的任务结果。下面编写事例代码,任务代码不变,执行任务的代码还是引用之前的,只不过需要将invorkAll方法改为invorkAny方法,并且将超时参数删掉。invorkAny方法直接返回任务执行结果,所以需要将集合改为单个结果。遍历结果的for循环也可以删掉了,输出执行结果也不需要调用get方法的,改为直接输出,这次例子改写完成,看看改写后的结果呈现输出。 五说明第五个任务是最先完成的。最后总结一下本节内容。本节介绍了执行批量任务的方法invorkAll和invorkAny它们的作用及用法,这里就不再赘述了。在实际开发中偶尔也会用到他们。
本文来自博客园,作者:小陈子博客,转载请注明原文链接:https://www.cnblogs.com/cj8357475/p/16032488.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本