All Downloads are FREE. Search and download functionalities are using the official Maven repository.

top.zeimao77.product.jobs.JobExecTemplate Maven / Gradle / Ivy

package top.zeimao77.product.jobs;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zeimao77
 * @version 2.0.9
 */
public abstract class JobExecTemplate implements JobExec{

    private static Logger logger = LoggerFactory.getLogger(JobExecTemplate.class);

    protected ArrayBlockingQueue jobs;
    protected ExecutorService executorService;
    protected JobExecHandler jobExecHandler;
    /**
     * 任务处理的扩展参数
     */
    protected Map jobParam;
    /**
     * 1:已准备好
     * @see JobExecTemplate#prepare()
     * 2:正在运行中
     * @see JobExecTemplate#start(int, long, TimeUnit)
     * 3:没有更多任务了,将不会再调用moreJob()
     * @see JobExecTemplate#moreJob(int)
     * 4:运行结束停止
     * @see JobExecTemplate#start(int, long, TimeUnit)
     * 5:请求立即停止任务,我们会在处理完当前任务之后立即停止
     * @see JobExecTemplate#setStatus(int)
     */
    protected int status = 0;

    /**
     *
     * @param executorService
     * @param nMaxJobs 单次调用添加任务的最大任务数
     */
    public JobExecTemplate(ExecutorService executorService,int nMaxJobs) {
        this.jobs = new ArrayBlockingQueue<>(nMaxJobs);
        this.executorService = executorService;
    }

    public JobExecTemplate(int nMaxJobs) {
        this.jobs = new ArrayBlockingQueue<>(nMaxJobs);
    }

    /**
     * 向任务队列添加任务,如果队列满会阻塞该进程
     * @param t 任务
     */
    public boolean addJob(T t) {
        try {
            jobs.put(t);
            return true;
        } catch (InterruptedException e) {
            logger.error("线程中断退出阻塞,可能丢失了任务JOBID:"+t.jobId(),e);
            Thread.currentThread().interrupt();
            return false;
        }
    }

    /**
     * 为了防止因任务执行失败重新添加回任务列表导致阻塞
     * 我们建议您的最多添加任务个数为:
     * jobs.size() - threadPoolExecutor.getCorePoolSize()
     */
    protected abstract void moreJob(int page);

    /**
     * 开始任务 默认10天超时时间
     * @param nThread 线程数
     */
    public void start(int nThread) {
        start(nThread,240,TimeUnit.HOURS);
    }

    /**
     * 开始任务
     * 如果任务执行超时或中断,剩余的任务将会被取消
     * 在执行过程中,可以通过调用 setStatus(5); 将结束任务,剩余的任务将被取消
     * @param nThreads 线程数
     * @param timeout 任务执行超时时间
     * @param unit 时间单位
     */
    public void start(int nThreads,long timeout, TimeUnit unit) {
        if(executorService == null) {
            executorService = Executors.newFixedThreadPool(nThreads);
        }
        setStatus(2);
        long start = System.currentTimeMillis();
        AtomicInteger page = new AtomicInteger(1);
        for (int i = 0; i < nThreads; i++) {
            executorService.execute(()->{
                while (status != 5 && !Thread.currentThread().isInterrupted()) {
                    T job =jobs.poll();
                    if(job == null) {
                        synchronized (this) {
                            if(jobs.isEmpty() && 2 == status) {
                                moreJob(page.getAndAdd(1));
                            }
                            job = jobs.poll();
                        }
                    }
                    if(job == null) {
                        logger.debug("线程({})没有取到更多任务,即将退出",Thread.currentThread().getName());
                        break;
                    }
                    jobExecHandler.handle(job,jobParam);
                }
            });
        }
        executorService.shutdown();
        try {
            if(!executorService.awaitTermination(timeout, unit)) {
                logger.error("线程池执行超时,剩余任务将被取消");
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            logger.error("线程中断退出阻塞",e);
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
        long end = System.currentTimeMillis();
        logger.info("任务执行结束,总共耗时:{}毫秒;",(end-start));
        if(status != 5) {
            setStatus(4);
        }
    }

    public JobExecHandler getJobExecHandler() {
        return jobExecHandler;
    }

    public void setJobExecHandler(JobExecHandler jobExecHandler) {
        this.jobExecHandler = jobExecHandler;
    }

    public Map getJobParam() {
        return jobParam;
    }

    public void setJobParam(Map jobParam) {
        this.jobParam = jobParam;
    }

    /**
     * 准备
     */
    public void prepare(){
        setStatus(1);
    }

    public synchronized void setStatus(int status) {
        this.status = status;
    }

    public int getStatus() {
        return status;
    }

    /**
     * 没有更多任务了,将不会再调用moreJob()
     */
    protected void over(){
        setStatus(3);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy