Java耗时任务怎么不重复执行

有时一段程序可能要运行几个小时才能完成,再次调用时他已经在运行中,不能再次从头开始运行,并且希望能返回现在运行的状态。

以下的方法是开一个线程来执行任务,标识执行状态,再次执行时根据标识来决定是否继续执行,返回执行信息。

先看一下调用方法:

StartInfo info=new LongTimeWorkThread(){
    public void doWork(){
       
        try {
            System.out.println("sleep 10秒开始 ");
            Thread.sleep(10000);
            System.out.println("sleep 10秒结束  ");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}.checkStart(TestLongTimeWorkThread.class.getName());

System.out.println("info:"+info);


再看看这个LongTimeWorkThread的实现代码:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public abstract class LongTimeWorkThread {
    private static ConcurrentHashMap<String,StartInfo> threadsFlag=new ConcurrentHashMap<String,StartInfo>();
    private static ExecutorService pool = Executors.newCachedThreadPool();
    private static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public StartInfo checkStart(String key){
        StartInfo flag=threadsFlag.get(key);
        if(flag==null||!flag.isDoingFlag()){
            if(flag==null){
                //第一次启动
                flag=new StartInfo(true,Calendar.getInstance().getTime(),"启动成功");
            }else{
                //非第一次启动,也不是在执行中
                flag.setDoingFlag(true);
                flag.setStartTime(Calendar.getInstance().getTime());
            }
            threadsFlag.put(key, flag);
            pool.execute(
                    new WorkThread(this,key){
                        public void run(){
                            try{
                                workObj.doWork();
                            }finally{
                                workObj.removeDoingFlag(key);
                            }
                        }
                    }
            );
            return flag;
        }else{
            flag.setInfo("本次启动失败,上次启动时间:"+sdf.format(flag.getStartTime()));
            return flag;
        }
    }
    public void removeDoingFlag(String key){
        StartInfo flag=threadsFlag.get(key);
        if(flag!=null){
            flag.setDoingFlag(false);
        }
    }
    public void shutdown(){
        pool.shutdown();
    }
   
    public class StartInfo{
        private boolean doingFlag;
        private String info;
        private Date startTime;
       
       
        public boolean isDoingFlag() {
            return doingFlag;
        }
        public void setDoingFlag(boolean doingFlag) {
            this.doingFlag = doingFlag;
        }
        public String getInfo() {
            return info;
        }
        public void setInfo(String info) {
            this.info = info;
        }
        public Date getStartTime() {
            return startTime;
        }
        public void setStartTime(Date startTime) {
            this.startTime = startTime;
        }
        public StartInfo(boolean doingFlag, Date startTime, String info) {
            super();
            this.doingFlag = doingFlag;
            this.info = info;
            this.startTime = startTime;
        }
        @Override
        public String toString() {
            return "StartInfo [doingFlag=" + doingFlag + ", info=" + info
                    + ", startTime=" + startTime + "]";
        }
       
       
       
    }
    /**
     * 调用者需实现该方法,执行具体的任务
     */
    public abstract void doWork();
    /**
     * 调用者可覆盖该方法返回错误的启动信息,先不用了,可在返回后拼接信息
     * @return
     */
    /*public String getFailInfo(){
        return "";
    }*/
}

class WorkThread extends Thread{
    public LongTimeWorkThread workObj;
    public String key;
    public WorkThread(LongTimeWorkThread workObj,String key){
        this.workObj=workObj;
        this.key=key;
    }
}

2019-06-11,优化并添加了分布式版本:

https://github.com/koolfret/longtimework

文/程忠 浏览次数:0次   2016-06-24 14:50:38

相关阅读

微信扫描-捐赠支持
加入QQ群-技术交流

评论:
点击刷新

↓ 广告开始-头部带绿为生活 ↓
↑ 广告结束-尾部支持多点击 ↑