任务会重试处理,关于scheduleWithFixedDelay定时线程池的使用

作者: admin 分类: JAVA,异常处理 发布时间: 2020-11-06 13:05  阅读: 311 views

需求

循环处理业务,当一个任务正常执行/延时执行后,顺延2s继续执行下一个。一个任务有点慢,所以就取5条吧。

Executors.newScheduledThreadPool()线程池的scheduleWithFixedDelay方法正好有这种处理机制。就姑且一试。

代码

package com.chl.thread.pool;

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 定时线程池
 * @author chl
 *
 */
public class ScheduledThreadPoolTest {

    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName()+" begin = "+new Date());
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        for(int i=0; i<5; i++){  //如果多个线程是有问题的, 单个线程成功
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            WorkerThread worker = new WorkerThread("--" +i);
            scheduledThreadPool.scheduleWithFixedDelay(worker, 5, 2, TimeUnit.SECONDS);
        }
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        scheduledThreadPool.shutdown();
        while(!scheduledThreadPool.isTerminated()){
        }
        System.out.println("Finished all threads");
    }

}

class WorkerThread implements Runnable{

private String command;

    public WorkerThread(String s){
        this.command=s;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" Start"+command.toString()+" Time = "+new Date());
        processCommand();
        System.out.println(Thread.currentThread().getName()+" End"+command.toString()+" Time = "+new Date());
    }

    private void processCommand() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString(){
        return this.command;
    }
}

以下是测试结果,

main begin = Fri Nov 06 11:57:09 CST 2020
pool-1-thread-1 Start--0 Time = Fri Nov 06 11:57:15 CST 2020
pool-1-thread-2 Start--1 Time = Fri Nov 06 11:57:16 CST 2020
pool-1-thread-3 Start--2 Time = Fri Nov 06 11:57:17 CST 2020
pool-1-thread-4 Start--3 Time = Fri Nov 06 11:57:18 CST 2020
pool-1-thread-5 Start--4 Time = Fri Nov 06 11:57:19 CST 2020
pool-1-thread-1 End--0 Time = Fri Nov 06 11:57:20 CST 2020
pool-1-thread-2 End--1 Time = Fri Nov 06 11:57:21 CST 2020
pool-1-thread-1 Start--0 Time = Fri Nov 06 11:57:22 CST 2020
pool-1-thread-3 End--2 Time = Fri Nov 06 11:57:22 CST 2020
pool-1-thread-4 End--3 Time = Fri Nov 06 11:57:23 CST 2020
pool-1-thread-2 Start--1 Time = Fri Nov 06 11:57:23 CST 2020
pool-1-thread-5 End--4 Time = Fri Nov 06 11:57:24 CST 2020
pool-1-thread-1 End--0 Time = Fri Nov 06 11:57:27 CST 2020
pool-1-thread-2 End--1 Time = Fri Nov 06 11:57:28 CST 2020
Finished all threads

发现什么问题没?thread-1、thread-2的任务重复执行了。

原因

这里有两个参数可以控制。

a. 线程数: 当变更为1个时,每次只处理一个线程就行了。
b. initialDelay参数, 只要保证线程内的任务执行时间不要超过这个值就不会重试了。

 public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit);

调整

将 initialDelay参数调整为6依然偶尔会有重试,设置为8后,不在出现

测试结果

main begin = Fri Nov 06 13:01:46 CST 2020
pool-1-thread-1 Start--0 Time = Fri Nov 06 13:01:55 CST 2020
pool-1-thread-2 Start--1 Time = Fri Nov 06 13:01:56 CST 2020
pool-1-thread-3 Start--2 Time = Fri Nov 06 13:01:57 CST 2020
pool-1-thread-4 Start--3 Time = Fri Nov 06 13:01:58 CST 2020
pool-1-thread-5 Start--4 Time = Fri Nov 06 13:01:59 CST 2020
pool-1-thread-1 End--0 Time = Fri Nov 06 13:02:00 CST 2020
pool-1-thread-2 End--1 Time = Fri Nov 06 13:02:01 CST 2020
pool-1-thread-3 End--2 Time = Fri Nov 06 13:02:02 CST 2020
pool-1-thread-4 End--3 Time = Fri Nov 06 13:02:03 CST 2020
pool-1-thread-5 End--4 Time = Fri Nov 06 13:02:04 CST 2020
Finished all threads

延伸

这个机制是不是可以利用起来做一些,回调重试处理呢? 有待研究


   原创文章,转载请标明本文链接: 任务会重试处理,关于scheduleWithFixedDelay定时线程池的使用

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

更多阅读