01 前言
先来看一些APP的获取数据,诸如此类,一个页面获取N多个,多达10个左右的一个用户行为数据,比如:点赞数,发布文章数,点赞数,消息数,关注数,收藏数,粉丝数,卡券数,红包数........... 真的是多~ 我们看些图:
![c72c7bab4da0250f0105fd3c98445633.png](https://i-blog.csdnimg.cn/blog_migrate/962cd12b2584ab95aa0ac0b1641a66e0.jpeg)
![3c10bdea19fb7c276d69db7ca49f8271.png](https://i-blog.csdnimg.cn/blog_migrate/234b0b89a0cb4464374f49a8024b83e8.jpeg)
平时要10+接口的去获取数据(因为当你10+个查询写一起,那估计到半分钟才能响应了),一个页面上N多接口,真是累死前端的宝宝了,前端开启多线程也累啊,我们做后端的要体量一下前端的宝宝们,毕竟有句话叫"程序员何苦为难程序员~"
今天我们也可以一个接口将这些数据返回~ 还贼TM快,解决串行编程,阻塞编程带来的苦恼~
02 多线程并发执行任务,取结果归集
今天猪脚就是 Future、FutureTask、ExecutorService...
- 用上FutureTask任务获取结果老少皆宜,就是CPU有消耗。FutureTask也可以做闭锁(实现了Future的语义,表示一种抽象的可计算的结果)。通过把Callable(相当于一个可生成结果的Runnable)作为一个属性,进而把它自己作为一个执行器去继承Runnable,FutureTask 实际上就是一个支持取消行为的异步任务执行器。
- Callable就是一个回调接口,可以泛型声明返回类型,而Runnable是线程去执行的方法.这个很简单~大家想深入了解就进去看源码好了~ 因为真的很简单~
- FutureTask实现了Future,提供了start, cancel, query等功能,并且实现了Runnable接口,可以提交给线程执行。
- Java并发工具类的三板斧 状态,队列,CAS
(1)状态
/** * The run state of this task, initially NEW. The run state * transitions to a terminal state only in methods set, * setException, and cancel. During completion, state may take on * transient values of COMPLETING (while outcome is being set) or * INTERRUPTING (only while interrupting the runner to satisfy a * cancel(true)). Transitions from these intermediate to final * states use cheaper ordered/lazy writes because values are unique * and cannot be further modified. * * Possible state transitions: //可能发生的状态过度过程 * NEW -> COMPLETING -> NORMAL // 创建-->完成-->正常 * NEW -> COMPLETING -> EXCEPTIONAL // 创建-->完成-->异常 * NEW -> CANCELLED // 创建-->取消 * NEW -> INTERRUPTING -> INTERRUPTED // 创建-->中断中-->中断结束 */ private volatile int state; // 执行器状态 private static final int NEW = 0; // 初始值 由构造函数保证 private static final int COMPLETING = 1; // 完成进行时 正在设置任务结果 private static final int NORMAL = 2; // 正常结束 任务正常执行完毕 private static final int EXCEPTIONAL = 3; // 发生异常 任务执行过程中发生异常 private static final int CANCELLED = 4; // 已经取消 任务已经取消 private static final int INTERRUPTING = 5; // 中断进行时 正在中断运行任务的线程 private static final int INTERRUPTED = 6; // 中断结束 任务被中断 /** The underlying callable; nulled out after running */ private Callable callable; /** The result to return or exception to throw from get() */ private Object outcome; // non-volatile, protected by state reads/writes /** The thread running the callable; CASed during run() */ private volatile Thread runner; /** Treiber stack of waiting threads */ private volatile WaitNode waiters;
还不明白就看图:
![b97130c914f60f85f641669a09ad146b.png](https://i-blog.csdnimg.cn/blog_migrate/621abbfc15c823fdaca2d8a0daaabb8f.jpeg)
![f6cee9044ea120f4df616b843d9700f1.png](https://i-blog.csdnimg.cn/blog_migrate/258d3c95f9d4bc0287ffe2127e5ba4bd.jpeg)
public interface Future { /** *取消任务 *@param mayInterruptIfRunning *是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务 *如果任务正在执行,则返回true *如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,返回true *如果任务已经完成,则无论mayInterruptIfRunning为true还是false,返回false */ boolean cancel(boolean mayInterruptIfRunning); /** *任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true */ boolean isCancelled(); /** *任务是否完成 */ boolean isDone(); /** *通过阻塞获取执行结果 */ T get() throws InterruptedException, ExecutionException; /** *通过阻塞获取执行结果。如果在指定的时间内没有返回,则返回null */ T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}
- Fu