利用future实现并行容器工具

利用future实现并行容器工具

使用场景

在平时的业务功能开发中,我们会遇到因为需要聚合多种下游的原子数据,会发起多次服务的调用链路,如图:

A
服务1
服务2
服务3

这样的调用链路,上下游的数据没有强依赖关系,但是却是一个串行的请求链路,请求->响应 在 发起请求,如果系统资源允许的话,利用异步线程能力可以降低接口响应耗时,提高用户体验。

线程工具类使用

异步线程执行器
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * 异步任务执行线程池
 */
public final class AsyncTaskExecutor {

    /**
     * 日志服务
     */
    private static final Logger               LOGGER               = LoggerFactory
                                                                       .getLogger(AsyncTaskExecutor.class);
    /**
     *
     */
    public static final int                   CORE_POOL_SIZE       = 80;

    /**
     * 默认最大
     */
    public static final int                   MAX_POOL_SIZE        = 400;

    /**
     * 默认超时毫秒
     */
    public int                                time_out             = 3000;

    /**
     * 默认超时时间单位
     */
    public TimeUnit                           time_out_unit        = TimeUnit.MILLISECONDS;

    /**
     * 线程池
     */
    private static final ThreadPoolExecutor   THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
                                                                       CORE_POOL_SIZE,
                                                                       MAX_POOL_SIZE, 500,
                                                                       TimeUnit.MILLISECONDS,
                                                                       new ArrayBlockingQueue(10),new ThreadFactoryBuilder().setNameFormat("async-task-pool-").build());

    /**  
     * future请求队列
     */
    private final LinkedBlockingQueue<Future> FUTURE_QUEUE;

    /**
     * 初始化队列大小
     * @param size
     */
    public AsyncTaskExecutor(int size) {
        FUTURE_QUEUE = new LinkedBlockingQueue<Future>(size);
    }

    /**
     * 设置任务超时时间
     * @param time
     * @param timeUnit
     */
    public void setTimeOut(int time, TimeUnit timeUnit){
        this.time_out = time;
        this.time_out_unit = timeUnit;
    }

    /**
     * 添加异步任务
     * @param function
     * @param param
     * @param <T>
     * @param <R>
     * @return
     */
    public <T, R> TaskEntry add(Function<T, R> function, T param) {
        // 声明一个对象引用
        final TaskEntry<R> entry = new TaskEntry<>();
        Future<R> future = THREAD_POOL_EXECUTOR.submit(new TracerCallable<R>() {

            @Override
            public R doCall() throws Exception {
                // 执行结果赋值给引用
                entry.setE(function.apply(param));
                return entry.getE();
            }
        });
        try {
            FUTURE_QUEUE.put(future);
        } catch (InterruptedException e) {
            LogUtil.error(LOGGER, e, "async Task 提交任务");
        }
        return entry;
    }

    /**
     * 执行任务,同步阻塞
     */
    public void executor() {
        FUTURE_QUEUE.forEach(e -> {
            try {
                e.get(time_out, time_out_unit);
            } catch (Exception e1) {
                LogUtil.error(LOGGER, e1, "执行async Task 任务失败");
            }
        });
    }

    /**
     * 任务结果对象
     * @param <E>
     */
    public static class TaskEntry<E> {

        /**
         * 结果引用
         */
        E e;

        /**
         * Getter method for property <tt>e</tt>.
         *
         * @return property value of e
         */
        public E getE() {
            return e;
        }

        /**
         * Setter method for property <tt>e</tt>.
         *
         * @param e value to be assigned to property e
         */
        public void setE(E e) {
            this.e = e;
        }
    }
}
初始任务队列 & 添加任务
// 初始化任务队列数
AsyncTaskExecutor asyncTask = new AsyncTaskExecutor(4);
// 添加任务, entry 就是执行结果的对象引用
                AsyncTaskExecutor.TaskEntry<List<A>> entry = asyncTask.add(new Function<String, List<A>>() {
                    @Override
                    public List<A> apply(String userId) {
                        return AManager.query(userId);
                    }
                }, userId);
执行任务
               // 执行线程任务, 会阻塞主线程,直到任务超时,或者全部返回结果
                asyncTask.executor();
运行效果
A
服务1
服务2
服务3
response
服务1,服务2,服务3
A
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值