最近在工做中使用到了spring自帶的Async,主要是爲了把其中耗時多、響應慢、計算複雜的業務抽取幾個模塊出來,並行查詢。不得不說spring自帶的比傳統線程池提交在代碼層次上看起來優雅簡潔了很多,直接返回一個AsyncResult,而後調用方經過Future接收。今天就打算本身手動實現這個異步組件,並藉此學習其中的原理。先思考一個問題,爲何直接調用一個普通的方法就能實現異步?第一個想到的就是代理,因此本章就從代理模式出發。java
整體實現思路流程:客戶端調用後-》經過代理模式代理-》重寫Submit方法並返回Future-》把Future 放到自定義的異步返回包裝類-》客戶端直接拿到返回的Future 進行get。git
public interface IAsyncProxy { /** * 獲取代理對象 * 1. 若是是實現了接口,默認使用 dynamic proxy 便可。 * 2. 若是沒有實現接口,默認使用 CGLIB 實現代理。 * @return 代理對象 */ Object proxy(); }
因爲代理分2種,接口的代理還有無接口的代理,因此這裏定義成接口方便擴展。github
public class DynamicProxy implements InvocationHandler, IAsyncProxy { /** * 被代理的對象 */ private final Object target; public DynamicProxy(Object target) { this.target = target; } /** * * * @param proxy 原始對象 * @param method 方法 * @param args 入參 * @return 結果 * @throws Throwable 異常 */ @Override @SuppressWarnings("all") public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return AsyncExecutor.submit(target, method, args); } @Override public Object proxy() { // 咱們要代理哪一個真實對象,就將該對象傳進去,最後是經過該真實對象來調用其方法的 InvocationHandler handler = new DynamicProxy(target); return Proxy.newProxyInstance(handler.getClass().getClassLoader(), target.getClass().getInterfaces(), handler); } }
因爲篇幅有限,這裏只講動態代理,至於Cglib代理實現方案和接口代理原理是一致的,能夠自行實現。其中最主要的是代理以後咱們要如何交給異步處理,在invoke方法內,我經過線程池去提交任務,細心的能夠發現AsyncExecutor在jdk包裏是沒有的,這個類是我本身定義的。至於緣由有如下幾個:spring
1.jdk自帶的ExecutorService的submit方法沒法知足, 因此須要從新實現ExecutorService作擴展,重寫submit方法。框架
2.submit以後須要包裝統一的返回結果,保持 實現類邊返回的類型和代理返回類型一致。異步
/** * <p> 異步執行結果 </p> / public interface IAsyncResult<T> extends Future<T> { /** * 獲取執行的結果 * @return 結果 */ Object getResult(); }
public abstract class AbstractAsyncResult<T> implements IAsyncResult<T> { @Override public boolean cancel(boolean mayInterruptIfRunning) { return false; } @Override public boolean isCancelled() { return false; } @Override public boolean isDone() { return false; } @Override public T get() throws InterruptedException, ExecutionException { try { return this.get(AsyncConstant.DEFAULT_TIME_OUT, TimeUnit.SECONDS); } catch (TimeoutException e) { throw new RuntimeException(e); } } }
/** * 異步執行結果 */ public class AsyncResult<T> extends AbstractAsyncResult<T> { /** * future 信息 */ private Future<T> future; /** * 結果 */ private Object value; /** * 獲取執行的結果 * @return 結果 */ @Override public Object getResult() { // 直接返回結果 if(future == null) { return this.getValue(); } try { T t = future.get(); // 這裏拿到的 AsyncResult 對象 if(null != t) { return ((AsyncResult)t).getValue(); } return null; } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } } @Override public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return future.get(timeout, unit); } public Object getValue() { return this.value; } public void setValue(Object value) { this.value = value; } public void setFuture(Future<T> future) { this.future = future; } }
/** * <p> 異步框架執行器 </p> public interface IAsyncExecutor extends ExecutorService { }
package com.github.houbb.async.core.executor; import java.util.concurrent.*; /** * 異步執行器 */ public class AsyncExecutor extends ThreadPoolExecutor implements IAsyncExecutor { //region 私有屬性 /** * 是否初始化 */ private static volatile boolean isInit = false; /** * 是否被銷燬 */ private static volatile boolean isDestroy = false; /** * 線程執行器 */ private static ExecutorService executorService = null; //endregion //region 構造器 public AsyncExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } public AsyncExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); } public AsyncExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); } public AsyncExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); } //endregion @SuppressWarnings("all") public static <T> IAsyncResult<T> submit(Object target, Method method, Object[] objects) { // 初始化的判斷 if(!isInit) { init(); } //經過線程池提交 Future future = executorService.submit(new Runnable() { @Override public void run() { try { method.invoke(target, objects); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); //Future future = executorService.submit(() -> method.invoke(target, objects)); AsyncResult<T> asyncResult = new AsyncResult<>(); asyncResult.setFuture(future); return asyncResult; } /** * 初始化 * 1. 暫時不添加配置相關的信息 * 2. 最後調整狀態 */ private static synchronized void init() { try { if(isInit) { return; } // 各類屬性配置 // 淘汰策略 // 最佳線程數量 executorService = Executors.newFixedThreadPool(10); updateExecutorStatus(true); } catch (Exception e) { throw new AsyncRuntimeException(e); } } /** * 銷燬容器 * 1. 銷燬的時候進行等待,確保任務的正常執行完成。 * 2. 任務執行的統計信息,後期添加。 */ private static synchronized void destroy() { if(isDestroy) { return; } executorService = null; updateExecutorStatus(false); } /** * 更新執行器的狀態 * @param initStatus 初始化狀態 */ private static void updateExecutorStatus(final boolean initStatus) { isInit = initStatus; isDestroy = !isInit; } }