05 阻塞式和定时式哪种获取任务的方式更好?

上一节我们简单的介绍一下future,这一节我们来介绍它里面最常用的功能,那就是获取任务执行结果的get方法。当我们通过submit的方法向线程池中提交一个runnable任务或者是callable任务时,他们执行完会将结果封装在对象中,然后再返回给调用者,调用者在通过future的get方法获得结果。future是一个接口,该接口定义与任务执行结果相关的功能。

 

 

 

 

如图所示。这些主要是介绍获取任务的功能。开始之前我先把两个比较简单的功能先介绍了,

就不再单独介绍,一个是isCancelled的方法,用于获取任务是否取消,已取消返回true,否则返回false,还有一个是isDone方法,用于获取任务是否完成,完成返回true,否则返回false。这两个方法还是用的比较多的。

下面着重来介绍这两个获取任务执行结果的方法。

无参的get方法

首先来看无参的get方法,该方法作用是获取任务执行结果,需要注意的是,它是一个阻塞方法,也就是说获取任务执行结果的线程会一直等到任务执行完毕,当任务执行完毕时,获取任务执行结果的线程才会继续往下执行。

 

 

任务执行过程中可能会发生一些异常,比如任务被取消时引发了异常,还有任务本身抛出来异常,以及执行任务的线程被中断时引发了异常。

 

 

下面我们来演示该方法,编写一个结果的任务,

任务内容是计算一加一的值,实现callable接口,加一的结果是整形,所以发型的类型是integer,重写call方法返回一加一的计算结果。至此方法编写完成。

 

 

接下来我们来执行该任务,首先将任务创建出来,然后创建一个线程池,这里我们就以单个线程池为例

至此main方法并且完成整个例子,

 

 

并且完成执行程序,观察执行结果。从执行结果来看,程序做出一加一的结果,二符合预期。关于这个方法大家需要注意一点,那就是她是阻塞的,很多人知道mian的方法可以获取任务执行结果,但很容易忽略他会阻塞线程。

get(long,timeUnit)

如果我们不想被无休止的住的话,那可以试试带定时功能的方法,比如我们定时三秒钟,如果三秒后还没出结果,那就不等获取任务的现场继续往下执行,如果三秒内出结果,那我们就拿着结果继续玩家执行

 

 

 

 

这样线程就不会被无休止的阻塞住。同无参的get方法功能一样,也是获取任务执行结果,同样是阻塞式的,只不过该方法有时间限制,超时则抛出异常。它有两个参数,第一个参数timeout可以指定等待任务执行结果的最长时间,第二个参数因为指定CAD的时间单位可以是时、分秒等,其他时间单位反馈的结果不用多说,任务执行的结果声明的异常同无参的方法一样,但比它多了一个超时异常,当等待超时时引发该异常。下面我们来演示该方法。

 

改之前的我们再返回结果之前使当前线程等待三秒钟。这样做的目的是模拟执行时间长的任务使call方法有异常抛出,因为call方法声明了一个异常,所以方法内部就不用捕获了。

 

 超时

执行任务的代码还是沿用之前的,只不过我们要给这个方法传递两个参数,综合前一个参数就是等待时间为一秒,刚刚我们的任务执行时间是至少三秒,所以我们这里定时一秒必然是等待超时。

 

 

带定时功能的get方法会抛出一个超时异常,使用try---catch捕获完成。

执行改写后的程序,观察执行结果。

 

 

从执行结果来看,程序发生超时异常符合预期。

不超时

再来看看未超时的情况,我们将超时时间一秒改为五秒,

 

 

改写程序观察执行结果,

 

 总结

从执行结果来看,程序这次没有引发超时异常。带参功能的方法相较于无参的方法来说,还是无参的方法,用的人更多,原因在于简单,方便快捷,一般提交给线程的任务都会一直等到任务执行结果出来为止。

我在日常开发中用无参的get方法更多一些,最后总结一下本节内容。本节介绍获取任务执行结果的方法,方法的用法和作用这里就不再赘述。在实际开发中,无声的方法用的更多。

 

 

 

 

posted @ 2022-03-18 10:27  小陈子博客  阅读(166)  评论(0)    收藏  举报