理解Executor接口的设计思路 | idouba

理解Executor接口的设计思路

Executor作为J.U.C的比较基础的功能功能,用到过,但理解不深,前阵子用线程池的时候把这部分源码扫了一遍,有些体会,记录下。记录下来感觉很简单,好像连记一下的必要都没有了,但是之前就是不理解。

Doug Lea大师的Executor所有的代码就这么些:

这个接口只定义了一个方法,就是execute传入的Runnable对象。意思也不难理解就是,执行Runnable中定义的内容。如果把传入的这个Runnable的参数理解为一个执行任务Task的描述,可能会更好理解。这个方法的作用就是把提交的这个task给execute起来。

很明显如果一个线程调用到这个方法,则会在这个线程中提交Task。但是Task怎么执行,什么时候执行,以哪种方式执行,是否有返回值,实在当前线程中执行还是在其他线程中执行,都不做要求,提交线程的方法只要保证把任务提交了,然后等会儿来能取到结果即可。

就像这个接口前面java doc举的最简单的例子,在方法里直接调用Task的Runnable方法,则在提交任务的线程中即可执行任务内定义的功能。

但是如果是不在当前线程中执行呢,在另外一个线程中运行。如doc中的另外一个例子:

调用的时候是重新创建一个线程,在该线程中调用Runnable对象中需要执行的任务。可能执行的逻辑还会更复杂,如使用线程池,使用某种调度策略来执行。

看到这里差不多就有点了解了。这个只定义了一个方法的接口最伟大的地方就是把任务的任务的提交和任务的运行解耦开了。调用Execute方法,我们只是提交了一个任务,但是任务的执行方式在Executor中定义。

举个例子,就像我们做一件事情,作为任务发布者,只需要把要干什么说清楚就好了,要得到什么结果约定好了,就可以把任务交出去,由承接任务的角色来完成,至于这个角色是一个包工队,是一个NB的个人,还是其他什么角色,只要在一定时间内完成即可。

执行两个任务我们不用必须如下的方式,就像定义任务的人自己去执行一样。

只是需要把任务提交就好了,至于这些任务怎么被执行的,什么时候开始执行,由什么线程来执行都不用关心了。

如下图不同的Executor提供了不同的实现,即不同的任务提交和运行方式。

Executor_class

其中就包括经常用到的线程池的方式支持任务提交和执行的ThreadPoolExecutor,和最经典的实现ScheduledThreadPoolExecutor,支持一定调度方法的线程池。

 

完。

原创文章。为了维护文章的版本一致、最新、可追溯,转载请注明: 转载自idouba

本文链接地址: 理解Executor接口的设计思路


, ,

No comments yet.

发表评论