前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并行执行任务思考

并行执行任务思考

作者头像
LiosWong
发布2018-10-29 17:42:36
4720
发布2018-10-29 17:42:36
举报
文章被收录于专栏:后端沉思录

问题

这篇文章由之前的并行执行任务发展而来,如何生成task,在之前的文章中,生成task方式如下:

代码语言:javascript
复制
Abstract Task: 
public abstract class BasicUserFilter implements Callable<UserFilterDto> {
private static final Log logger = LogFactory.getLog(BasicUserFilter.class);
@Autowired
UserService userService;
public Long companyId;
public Long userId;
@Override
public UserFilterDto call() throws Exception {
    try {
        //每个执行任务调用同一个方法,只是入参不同
        Response<Boolean> response = userService.filter(getUserId(), getCompanyId());
        if (response.isSuccess() && response.getResult()) {
            return new UserFilterDto().setCompanyId(getCompanyId()).setUserId(getUserId()).setFilterResultEnum(FilterResultEnum.TRUE);
        }
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    }
    return new UserFilterDto().setCompanyId(getCompanyId()).setUserId(getUserId()).setFilterResultEnum(FilterResultEnum.FALSE);
}
@PostConstruct
abstract void init();
// ... 篇幅关系,省略属性setter、getter方法
}
}

Task1:
public class Task1 extends BasicUserFilter{
    @Override
    public void init() {
        FilterConfigManager.register(CompanyAppIdEnum.GEI_NI_HUA.getCompanyId(),this);
    }
    @Override
    public UserFilterDto call() throws Exception {
        return super.call();
    }
}

上面生成任务类时,使用了策略模式,添加每一个任务都必须新增一个实体类,且实现BasicUserFilter或者重写自己的 call方法,有木有比较好的方法解决这种繁琐的任务类构建呢。

方案

解决切入点,就是所有的任务类都执行了相同的逻辑,且调用了入参不同的方法而已,无疑使用代理模式去动态生成任务类,思路有了,代码实现也边的简单起来。下面使用java InvocationHandler创建动态代理类.

代码语言:javascript
复制
ProxyHandler:
/**
 * @author LiosWong
 * @description
 * @date 2018/10/27 上午1:10
 */
public class ProxyHandler<T> implements InvocationHandler, Serializable {
    private static final long serialVersionUID = -6424540398559729838L;
    private final ProxyInterface<T> proxyInterface;

    public ProxyHandler(ProxyInterface<T> proxyInterface) {
        this.proxyInterface = proxyInterface;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 根据方法名,执行不同逻辑
        if ("call".equals(method.getName())) {
            return proxyInterface.call();
        }
        return null;
    }
}
ProxyInterface:为了使代理模版通用,添加接口约束
/** 
 * @author LiosWong
 * @description 可扩展代理接入点
 * @date 2018/10/27 上午1:11
 */
public interface ProxyInterface<T> extends Callable<T> {

}
ProxyFactory:代理工厂
public class ProxyFactory<T> {
private final Class<T> mapperInterface;

public ProxyFactory(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
}
public Class<T> getMapperInterface() {
    return mapperInterface;
}
@SuppressWarnings("unchecked")
protected T newInstance(ProxyHandler<T> mapperProxy) {
    return (T) java.lang.reflect.Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);
}
public T newInstance(ProxyInterface proxyInterface) {
    final ProxyHandler<T> mapperProxy = new ProxyHandler<T>(proxyInterface);
    return newInstance(mapperProxy);
}
}

完成了上面的动态代理类构建,下面就是在业务代码中使用:

代码语言:javascript
复制
ProxyFactory proxyFactory = new ProxyFactory<Callable>(Callable.class);
        List<Callable<UserFilterDto>> callableList = new ArrayList<>();
        List<UserFilterDto> filterDtosResult = new ArrayList<>();
        // 动态生成代理类
        list.forEach(p -> {
            Callable<UserFilterDto> callable = null;
            // 复用代理模版
            switch (concurrencyType) {
                case FILTER:
                    callable = (Callable<UserFilterDto>) proxyFactory.newInstance(new ProxyFilterCallable(xjUserService, userId, p.getCompanyId()));
                    break;
                case SATISFY:
                    callable = (Callable<UserFilterDto>) proxyFactory.newInstance(new ProxySatisfyCallable(companyUserGroupService, userId, p.getCompanyId()));
                    break;
                default:
                    break;
            }
            callableList.add(callable);
        });

ProxyFilterCallable:

代码语言:javascript
复制
public class ProxyFilterCallable<T> implements ProxyInterface<T> {
    private static final Log logger = LogFactory.getLog(ProxyFilterCallable.class);
    private UserService userService;
    private Long userId;
    private Long companyId;

    public ProxyFilterCallable(XjUserService xjUserService, Long userId, Long companyId) {
        this.xjUserService = xjUserService;
        this.userId = userId;
        this.companyId = companyId;
    }
    @Override
    public T call() throws Exception {
        try {
            Response<Boolean> response = userService.filter(getUserId(), getCompanyId());
            if (response.isSuccess() && response.getResult()) {
                return (T) new UserFilterDto().setCompanyId(getCompanyId()).setUserId(getUserId()).setFilterResultEnum(FilterResultEnum.TRUE);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return (T) new UserFilterDto().setCompanyId(getCompanyId()).setUserId(getUserId()).setFilterResultEnum(FilterResultEnum.FALSE);
    }
    // ...
}

ProxySatisfyCallable:

代码语言:javascript
复制
public class ProxySatisfyCallable<T> implements ProxyInterface<T> {
    private static final Log logger = LogFactory.getLog(ProxyFilterCallable.class);
    private CompanyUserGroupService companyUserGroupService;
    private Long userId;
    private Long companyId;

    public ProxySatisfyCallable(CompanyUserGroupService companyUserGroupService, Long userId, Long companyId) {
        this.companyUserGroupService = companyUserGroupService;
        this.userId = userId;
        this.companyId = companyId;
    }

    @Override
    public T call() throws Exception {
        try {
            XjFilterUserResultVo xjFilterUserResultVo = companyUserGroupService.checkUserInfoIsSatisfyCompany(getUserId(), getCompanyId());
            if (Objects.nonNull(xjFilterUserResultVo) && xjFilterUserResultVo.getResult()) {
                return (T) new UserFilterDto().setCompanyId(getCompanyId()).setUserId(getUserId()).setFilterResultEnum(FilterResultEnum.TRUE);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return (T) new UserFilterDto().setCompanyId(getCompanyId()).setUserId(getUserId()).setFilterResultEnum(FilterResultEnum.FALSE);
    }
    // ...
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端沉思录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
  • 方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档