线程池进行分布式多任务并行处理模板代码

本文介绍了如何使用线程池处理分布式环境中从Redis列表中获取的任务。每个任务处理时间约为60秒,若Redis列表中在2秒内无任务则会继续查询。文中涉及分布式任务接口、行为类型、状态以及异常处理,并提供了延迟和定期执行的线程池模板代码。
摘要由CSDN通过智能技术生成

场景:多个任务提交到redis的list中,多机器部署,每台机器都是在启动项目的时候启动这个从redis的list中pop任务进行处理,如果redis的list中等待timeout=2s没有数据就会再次去list中去取task;任务处理比较耗时,大概将近60s处理完毕

  1. 基于redis的分布式任务提交处理的线程池
public abstract class AbstractDistributedTaskHandler extends ThreadPoolExecutor {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    //根据自己的redis进行相应的调整
    private ListCommands listCommands;
    private HashCommands hashCommands;
    private boolean running;
    private final HashMap<Integer, ProjectFutureTask> tasks = new HashMap<>(100);
    private TimeUnit taskTimeoutTimeUnit = TimeUnit.MINUTES;
    private long taskTimeout = 30;
    
    public AbstractDistributedTaskHandler() {
        this(5, "task");
    }

    /**
     * 构造当前节点线程池
     *
     * @param poolSize 用于提交用户的线程池大小,另外增加2个内部线程用于提交和检测超时
     */
    public AbstractDistributedTaskHandler(int poolSize, String poolThreadName) {
        super(poolSize + 2, poolSize + 2, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100), new NamedThreadFactory(poolThreadName), new AbortPolicy());
    }

    /**
     * 初始化方法
     */
    public final void init() {
        listCommands = RedisFactory.getClusterListCommands(getRedisGroupName());
        hashCommands = RedisFactory.getClusterHashCommands(getRedisGroupName());
    }

    /**
     * 开始启动接收分布式线程
     *
     * @param taskTimeoutTimeUnit 每个线程超时时间单位
     * @param taskTimeout         每个线程超时时间
     */
    public final void start(TimeUnit taskTimeoutTimeUnit, long taskTimeout) {
        this.taskTimeoutTimeUnit = taskTimeoutTimeUnit;
        this.taskTimeout = taskTimeout;
        this.running = true;
        execute(() -> fetchNewTask());
        execute(() -> checkTaskTimeout());
    }

    @Override
    public void shutdown() {
        running = false;
        super.shutdown();
    }

    /**
     * 开始从redis获取任务并提交到线程池
     */
    private void fetchNewTask() {
        while (running) {
            if (getActiveCount() >= getCorePoolSize()) {
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                continue;
            }
            Task task = listCommands.rightPop(getRedisNamespace(), getTaskQueueRedisKey(), 2, TimeUnit.SECONDS, true);
            if (task != null) {
                ProjectFutureTask future = new ProjectFutureTask(task);
                execute(future);
                tasks.put(task.getTaskId(), future);
            }
        }
    }

    /**
     * 开始线程池中的线程超时检查
     */
    private void checkTaskTimeout() {
        while (running) {
            Iterator<Map.Entry<Integer, ProjectFutureTask>> it = tasks.entrySet().iterator();
            while (it.hasNext()) {
                ProjectFutureTask futureTask = it.next().getValue();
                if (futureTask.isDone() || futureTask.isCancelled()) {
                    it.remove();
                } else if (System.currentTimeMillis() - futureTask
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值