【原】手寫spring async異步組件

   最近在工作中使用到了spring自帶的Async,主要是爲了把其中耗時多、響應慢、計算複雜的業務抽取幾個模塊出來,並行查詢。不得不說spring自帶的比傳統線程池提交在代碼層次上看起來優雅簡潔了不少,直接返回一個AsyncResult,然後調用方通過Future接收。今天就打算自己手動實現這個異步組件,並藉此學習其中的原理。先思考一個問題,爲什麼直接調用一個普通的方法就能實現異步?第一個想到的就是代理,所以本章就從代理模式出發。

     總體實現思路流程:客戶端調用後-》通過代理模式代理-》重寫Submit方法並返回Future-》把Future 放到自定義的異步返回包裝類-》客戶端直接拿到返回的Future 進行get。

 

 

1.新建代理接口


public interface IAsyncProxy {

    /**
     * 獲取代理對象
     * 1. 如果是實現了接口,默認使用 dynamic proxy 即可。
     * 2. 如果沒有實現接口,默認使用 CGLIB 實現代理。
     * @return 代理對象
     */
    Object proxy();

}

 由於代理分2種,接口的代理還有無接口的代理,所以這裏定義成接口方便擴展。

2.新建動態代理實現類

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包裏是沒有的,這個類是我自己定義的。至於原因有以下幾個:

        1.jdk自帶的ExecutorService的submit方法無法滿足, 所以需要重新實現ExecutorService做擴展,重寫submit方法。

        2.submit之後需要包裝統一的返回結果,保持 實現類邊返回的類型和代理返回類型一致。

3.定義異步接口

/**
 * <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;
    }

}

  

4.定義一個異步接口,繼承ExecutorService 

/**
 * <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;
    }

}

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章