有时一段程序可能要运行几个小时才能完成,再次调用时他已经在运行中,不能再次从头开始运行,并且希望能返回现在运行的状态。
以下的方法是开一个线程来执行任务,标识执行状态,再次执行时根据标识来决定是否继续执行,返回执行信息。
先看一下调用方法:
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 threadsFlag=new ConcurrentHashMap();
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
评论:
提交