笔者今天学习FutureTask包装器,简单点讲该包装器就是对底层线程任务执行的包装,包括返回值,异常抛出等。好比说咱们如今有个任务须要交个run方法进行执行,这时候咱们调用Thread的start方法,而后JVM开启一个线程帮咱们执行该方法,可是run返回值为void,而且不能抛出异常,这是就须要包装器对其进行包装。今天笔者就来本身实现下FutureTask简单的底层实现原理。函数
- 首先建立MyCallable接口,添加未实现的myCall的方法该方法返回T类型的返回值,后面交给自定义MyFutureTask任务包装器执行。

- 编写MyFutureTask类实现Runnable接口,为何实现这个接口呢,由于咱们须要将myCall接口交给JVM底层的线程去执行。一般Thread的构造函数会传入Runnable接口进去。而后调用Runnable的run方法。等会咱们也须要开启一个线程传入MyFutureTask对象进行。让底层开启一个线程帮咱们执行MyFutureTask的fun方法。

- MyFutureTask里面须要对MyCallable进行引用,而且经过构造方法对其进行赋值,在MyFutureTask的run方法对MyCallable的myCall方法进行执行。myCall有返回值因此咱们须要定义个全局的结果来对其进行存储。可是咱们如何判断当前线程是否执行完毕,因此咱们引入了一个简单的线程状态(固然真正的底层线程状态会比较多)只有NEW和COMPLETE,NEW表示线程建立而且任务还未执行完,COMPLETE表示线程已经执行完任务。

- MyFutureTask的重写Runnable的run方法,调用myCallable的myCall的方法执行任务,并获取返回结果。这里JVM底层会开启一个线程帮咱们执行run方法。

- FutureTask的会提供get来获取任务执行结果,因此咱们也简单模拟了get的实现原理。在get方法中咱们去判断线程任务的执行状态,若是状态为COMPLETE则将结果返回出去,若是不为COMPLETE则当前线程调用wait方法进入等待状态。(注意这里其实有两个不一样的线程。一般主线程会执行get方法,而另一个线程执行run方法。)

- 接着在run方法中若是线程任务执行完后,这修改其状态为COMPLETE,并唤醒等待的线程。这里涉及到了线程的通信,我只简单的提一下,后续会有专题进行记录。

- 最后进行测试

