Commit 09c59889 authored by yanzg's avatar yanzg

线程相关处理

parent 5ee7bdd0
......@@ -7,10 +7,22 @@ public class ExceptionHelper {
/**
* 不跑出异常,记录日常日志
*
* @param cls
* @param ex
*/
public static void handleException(Class<?> cls, Throwable ex) {
handleException(cls, ex, null);
}
/**
* 不跑出异常,记录日常日志
*
* @param cls
* @param ex
* @param from
*/
public static void handleException(Throwable ex, Object from) {
public static void handleException(Class<?> cls, Throwable ex, Object from) {
ex.printStackTrace();
// todo: 需要修改
// Log.error(ExceptionHelper.class, ex, StringHelper.toString(from));
}
......
......@@ -2,6 +2,7 @@ package com.yanzuoguang.util.helper;
import com.yanzuoguang.util.exception.CodeException;
import com.yanzuoguang.util.helper.thread.ThreadHelper;
/**
* 重复执行工具类
......
package com.yanzuoguang.util.helper;
import java.util.ArrayList;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadHelper {
private static Object _ThreadLock = new Object();
private static boolean _ThreadIsRun = false;
private static Date _ThreadDate = null;
private static ExecuteRun Timeout;
private static ExecuteRun Interval;
private static void InitStatic() {
_ThreadDate = StringHelper.GetDateTime("1987-11-04");
Timeout = new ExecuteRun();
Interval = new ExecuteRun();
ThreadDelegateCode vAdd = new ThreadDelegateCode() {
public void Execute() {
OnExecuteAdd();
}
};
ThreadDelegateCode vItemAdd = new ThreadDelegateCode() {
public void Execute() {
OnItemExecuted();
}
};
Timeout.OnAdd.Add(vAdd);
Timeout.OnItemExecuted.Add(vItemAdd);
Interval.OnAdd.Add(vAdd);
Interval.OnItemExecuted.Add(vItemAdd);
StartMonitor();
}
// #region 内部累
private static class ExecuteData {
public Date Date;
public double ExecuteCount;
public double ExecuteError; // 调试变量
public String Flag;
public int Time;
public ThreadDelegateCode Execute;
public ExecuteData() {
this.Date = new Date();
}
}
public static class ExecuteRun {
private Object m_Lock = new Object();
private ArrayList<ExecuteData> m_List = new ArrayList<ExecuteData>();
private Event<ThreadDelegateCode> OnAdd = new Event<ThreadDelegateCode>();
private Event<ThreadDelegateCode> OnRemove = new Event<ThreadDelegateCode>();
private Event<ThreadDelegateCode> OnItemExecuted = new Event<ThreadDelegateCode>();
private Event<ThreadDelegateCode> OnExecuted = new Event<ThreadDelegateCode>();
public Event<ThreadDelegateCode> GetOnAdd() {
return OnAdd;
}
public Event<ThreadDelegateCode> GetOnRemove() {
return OnRemove;
}
public Event<ThreadDelegateCode> GetOnItemExecuted() {
return OnItemExecuted;
}
public Event<ThreadDelegateCode> GetOnExecuted() {
return OnExecuted;
}
/**
* 执行完任务后,是否需要删除该任务,并且设置允许执行的最大错误
*
* @param vIsRemove
* @param vMaxError
*/
public final void Execute(boolean vIsRemove, int vMaxError) {
for (int i = m_List.size() - 1; i >= 0; i--) {
Date vNow = new Date();
ExecuteData vItem = null;
synchronized (this.m_Lock) {
vItem = m_List.size() > i ? m_List.get(i) : null;
}
if (vItem == null) {
continue;
}
double vMillseconds = 0;
// 在Window CE中时间相减可能会出错
try {
// 处理非法改动时间
if (vItem.Date.compareTo(vNow) > 0) {
vItem.Date = vNow;
}
vMillseconds = (vNow.getTime() - vItem.Date.getTime());
} catch (Exception ex) {
Log.error(ThreadHelper.class, ex);
}
// 未到执行时间
if (vMillseconds <= vItem.Time) {
continue;
}
if (vMaxError == -1 || vItem.ExecuteError < vMaxError) {
try {
vItem.ExecuteCount++;
vItem.ExecuteError++;
vItem.Execute.Execute();
vItem.ExecuteError = 0;
this.ExecuteEvent(this.OnItemExecuted);
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
vItem.Date = new Date();
}
try {
if (vIsRemove) {
synchronized (this.m_Lock) {
this.m_List.remove(i);
this.ExecuteEvent(this.OnRemove);
}
}
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
}
this.ExecuteEvent(this.OnExecuted);
}
/**
* 设置需要执行的任务
*
* @param vExecute 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public final String Set(ThreadDelegateCode vExecute, int vTime) {
ExecuteData tempVar = new ExecuteData();
tempVar.Flag = StringHelper.
tempVar.Execute = vExecute;
tempVar.Time = vTime;
ExecuteData vData = tempVar;
synchronized (m_Lock) {
m_List.add(vData);
}
this.ExecuteEvent(this.OnAdd);
return vData.Flag;
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public final void Clear(String flag) {
synchronized (m_Lock) {
for (ExecuteData item : this.m_List) {
if (item.Flag.equals(flag)) {
this.m_List.remove(item);
this.ExecuteEvent(this.OnRemove);
break;
}
}
}
}
/**
* 清除需要执行的任务
*
* @param vExecute 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public final void Clear(ThreadDelegateCode vExecute) {
synchronized (m_Lock) {
for (ExecuteData item : this.m_List) {
if (item.Execute == vExecute) {
this.m_List.remove(item);
this.ExecuteEvent(this.OnRemove);
break;
}
}
}
}
private void ExecuteEvent(Event<ThreadDelegateCode> vExecute) {
try {
if (vExecute != null) {
vExecute.Exeucte(new ThreadDelegateCodeExecute());
}
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
}
public final int getCount() {
return this.m_List.size();
}
}
private static void OnItemExecuted() {
_ThreadDate = new Date();
}
private static void OnExecuteAdd() {
StartThread();
}
private static void StartThread() {
synchronized (_ThreadLock) {
if (_ThreadIsRun) {
return;
}
RunThread(new ThreadDelegateCode() {
public void Execute() throws Exception {
_ThreadIsRun = true;
while (_ThreadIsRun) {
try {
Timeout.Execute(true, -1);
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
try {
Interval.Execute(false, -1);
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
if (Timeout.getCount() == 0 && Interval.getCount() == 0) {
break;
}
Thread.sleep(10);
}
_ThreadIsRun = false;
}
});
}
}
static {
// InitStatic();
}
/**
* 监控线程的方法,防止线程执行死机
*/
private static void StartMonitor() {
RunThread(new ThreadDelegateCode() {
public void Execute() throws Exception {
do {
if (_ThreadIsRun && ((new Date().getTime() - _ThreadDate.getTime()) / 1000) > 5) {
try {
if (_ThreadIsRun) {
_ThreadIsRun = false;
}
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
_ThreadIsRun = false;
StartThread();
}
Thread.sleep(1000 * 60);
} while (true);
}
});
}
/**
* 多少毫秒后执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param vFrom
* 需要执行的窗体
* @param vExecute
* 需要执行的程序
* @param vTime
* 间隔时间
* @return 执行标志
*/
// public static String SetTimeout(Form vForm, ThreadDelegateCode vExecute,
// int vTime)
// {
// return Timeout.Set(vForm, vExecute, vTime);
// }
/**
* 多少毫秒后执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param vExecute 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public static String SetTimeout(ThreadDelegateCode vExecute, int vTime) {
return Timeout.Set(vExecute, vTime);
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public static void ClearTimeout(String flag) {
Timeout.Clear(flag);
}
/**
* 清除需要执行的任务
*
* @param vExecute 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public static void ClearTimeout(ThreadDelegateCode vExecute) {
Timeout.Clear(vExecute);
}
/**
* 每隔多少毫秒执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param vFrom
* 需要执行的窗体
* @param vExecute
* 需要执行的程序
* @param vTime
* 间隔时间
* @return 执行标志
*/
// public static String SetInterval(Form vForm, ThreadDelegateCode vExecute,
// int vTime)
// {
// return Interval.Set(vForm, vExecute, vTime);
// }
/**
* 每隔多少毫秒执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param vExecute 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public static String SetInterval(ThreadDelegateCode vExecute, int vTime) {
return Interval.Set(vExecute, vTime);
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public static void ClearInterval(String flag) {
Interval.Clear(flag);
}
/**
* 清除需要执行的任务
*
* @param vExecute 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public static void ClearInterval(ThreadDelegateCode vExecute) {
Interval.Clear(vExecute);
}
public static void Sleep(int p) {
try {
Thread.sleep(p);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void ExecuteCatch(ThreadDelegateCode vExecute) {
try {
vExecute.Execute();
} catch (Exception ex) {
ex.printStackTrace();
Log.error(ThreadHelper.class,ex);
}
}
private static ExecutorService _ExecuteService = Executors.newCachedThreadPool();
public static void RunThread(final ThreadDelegateCode vExecute) {
_ExecuteService.execute(new Runnable() {
@Override
public void run() {
ExecuteCatch(vExecute);
}
});
}
public static void RunThread(final RunInterval vInterval) {
RunThread(new ThreadDelegateCode() {
public void Execute() throws Exception {
while (!vInterval.getBreak()) {
try {
vInterval.getCode().Execute();
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
Thread.sleep(vInterval.getTime());
}
}
});
}
public static void sleep(long timer) {
try {
Thread.sleep(timer);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
package com.yanzuoguang.util.helper.thread;
import com.yanzuoguang.util.helper.EventRun;
/**
* Runnable时间触发处理器
*/
public class RunExecute implements EventRun<Runnable> {
/**
* 执行时间
*
* @param t 接口 需要执行的对象
* @throws Exception 跑出异常
*/
public void Execute(Runnable t) {
t.run();
}
}
package com.yanzuoguang.util.helper.thread;
/**
* 循环执行任务
*/
public class RunInterval {
/**
* 当前线程
*/
private Thread Thread;
/**
* 间隔时间,毫秒
*/
private int Time;
/**
* 执行的代码
*/
private Runnable Code;
/**
* 是否终端
*/
private boolean Break;
public java.lang.Thread getThread() {
return Thread;
}
public void setThread(java.lang.Thread thread) {
Thread = thread;
}
public int getTime() {
return Time;
}
public void setTime(int time) {
Time = time;
}
public Runnable getCode() {
return Code;
}
public void setCode(Runnable code) {
Code = code;
}
public boolean isBreak() {
return Break;
}
public void setBreak(boolean aBreak) {
Break = aBreak;
}
}
\ No newline at end of file
package com.yanzuoguang.util.helper.thread;
import com.yanzuoguang.util.helper.Event;
import com.yanzuoguang.util.helper.ExceptionHelper;
import com.yanzuoguang.util.helper.StringHelper;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 自动执行任务
*/
public class RunPlan {
// 任务锁
private Object m_Lock = new Object();
// 任务队列
private List<RunPlanData> m_List = new ArrayList<>();
// 增加时触发的事件队列
private Event<Runnable> onAdd = new Event<>();
// 增加时触发的事件队列
private Event<Runnable> onRemove = new Event<>();
// 单项成功执行时的事件队列
private Event<Runnable> onItemExecuted = new Event<>();
// 全部执行完时触发的事件队列
private Event<Runnable> onExecuted = new Event<>();
/**
* 增加时触发的事件队列
*
* @return 事件队列
*/
public Event<Runnable> getOnAdd() {
return onAdd;
}
/**
* 增加时触发的事件队列
*
* @return 事件队列
*/
public Event<Runnable> getOnRemove() {
return onRemove;
}
/**
* 单项成功执行时的事件队列
*
* @return 事件队列
*/
public Event<Runnable> getOnItemExecuted() {
return onItemExecuted;
}
/**
* 全部执行完时触发的事件队列
*
* @return 事件队列
*/
public Event<Runnable> getOnExecuted() {
return onExecuted;
}
/**
* 执行完任务后,是否需要删除该任务,并且设置允许执行的最大错误
*
* @param isRemove 执行完成是否删除
* @param maxError 最大错误次数
*/
public final void Execute(boolean isRemove, int maxError) {
for (int i = m_List.size() - 1; i >= 0; i--) {
Date now = new Date();
RunPlanData item;
synchronized (this.m_Lock) {
item = m_List.size() > i ? m_List.get(i) : null;
}
if (item == null) {
continue;
}
double millSeconds = 0;
// 在Window CE中时间相减可能会出错
try {
// 处理非法改动时间
if (item.getDate().compareTo(now) > 0) {
item.setDate(now);
}
millSeconds = (now.getTime() - item.getDate().getTime());
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex);
}
// 未到执行时间
if (millSeconds <= item.getTime()) {
continue;
}
if (maxError == -1 || item.getExecuteError() < maxError) {
try {
item.addCount();
item.getExecute().run();
item.initError();
this.triggerEvent(this.onItemExecuted);
} catch (Exception ex) {
ExceptionHelper.handleException(RunPlan.class, ex);
}
item.initDate();
}
try {
if (isRemove) {
synchronized (this.m_Lock) {
this.m_List.remove(i);
this.triggerEvent(this.onRemove);
}
}
} catch (Exception ex) {
ExceptionHelper.handleException(RunPlan.class, ex);
}
}
this.triggerEvent(this.onExecuted);
}
/**
* 设置需要执行的任务
*
* @param run 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public final String Set(Runnable run, int vTime) {
// 创建临时任务数据
RunPlanData temp = new RunPlanData();
temp.setFlag(StringHelper.getNewID());
temp.setExecute(run);
temp.setTime(vTime);
synchronized (m_Lock) {
m_List.add(temp);
}
this.triggerEvent(this.onAdd);
return temp.getFlag();
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public final void remove(String flag) {
synchronized (m_Lock) {
for (RunPlanData item : this.m_List) {
if (item.getFlag().equals(flag)) {
this.m_List.remove(item);
this.triggerEvent(this.onRemove);
break;
}
}
}
}
/**
* 清除需要执行的任务
*
* @param run 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public final void remove(Runnable run) {
synchronized (m_Lock) {
for (RunPlanData item : this.m_List) {
if (item.getExecute().equals(run)) {
this.m_List.remove(item);
this.triggerEvent(this.onRemove);
break;
}
}
}
}
/**
* 触发事件
*
* @param run 需要触发的事件队列
*/
private void triggerEvent(Event<Runnable> run) {
try {
if (run != null) {
run.exeucte(new RunExecute());
}
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex);
}
}
/**
* 获取需要执行的任务长度
*
* @return 长度信息
*/
public final int getCount() {
return this.m_List.size();
}
}
package com.yanzuoguang.util.helper.thread;
import java.util.Date;
/***
* 任务项数据
*/
public class RunPlanData {
/**
* 任务开始时间
*/
private Date date;
/**
* 执行标记
*/
private String flag;
/**
* 执行次数
*/
private double executeCount;
/**
* 执行时错误次数
*/
private double executeError; // 调试变量
/**
* 执行时间
*/
private int time;
/**
* 需要执行的对象
*/
private Runnable execute;
/**
* 构造函数
*/
public RunPlanData() {
this.initDate();
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
public double getExecuteCount() {
return executeCount;
}
public void setExecuteCount(double executeCount) {
this.executeCount = executeCount;
}
public double getExecuteError() {
return executeError;
}
public void setExecuteError(double executeError) {
this.executeError = executeError;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public Runnable getExecute() {
return execute;
}
public void setExecute(Runnable execute) {
this.execute = execute;
}
/**
* 添加执行次数
*/
public void addCount() {
this.executeCount++;
this.executeError++;
}
/**
* 添加执行次数
*/
public void initError() {
this.executeError = 0;
}
/**
* 重置时间
*/
public void initDate() {
this.date = new Date();
}
}
package com.yanzuoguang.util.helper.thread;
import com.yanzuoguang.util.helper.DateHelper;
import com.yanzuoguang.util.helper.ExceptionHelper;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 线程帮助类
*/
public class ThreadHelper {
private static Object threadLock = new Object();
private static boolean threadIsRun = false;
private static Date threadDate = null;
private static RunPlan timeout;
private static RunPlan interval;
// 线程对象
private static ExecutorService _ExecuteService = Executors.newCachedThreadPool();
/**
* 初始化线程对象,需要调用该函数之后才能使用
*/
public static void init() {
if (timeout != null || interval != null) {
return;
}
threadDate = DateHelper.getDateTime("1987-11-04");
timeout = new RunPlan();
interval = new RunPlan();
Runnable addExecute = new Runnable() {
public void run() {
OnExecuteAdd();
}
};
Runnable itemExecuted = new Runnable() {
public void run() {
OnItemExecuted();
}
};
timeout.getOnAdd().add(addExecute);
timeout.getOnItemExecuted().add(itemExecuted);
interval.getOnAdd().add(addExecute);
interval.getOnItemExecuted().add(itemExecuted);
StartMonitor();
}
private static void OnItemExecuted() {
threadDate = new Date();
}
private static void OnExecuteAdd() {
startThread();
}
private static void startThread() {
synchronized (threadLock) {
if (threadIsRun) {
return;
}
runThread(new Runnable() {
public void run() {
threadIsRun = true;
while (threadIsRun) {
try {
timeout.Execute(true, -1);
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex);
}
try {
interval.Execute(false, -1);
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex);
}
if (timeout.getCount() == 0 && interval.getCount() == 0) {
break;
}
sleep(10);
}
threadIsRun = false;
}
});
}
}
/**
* 监控线程的方法,防止线程执行死机
*/
private static void StartMonitor() {
runThread(new Runnable() {
public void run() {
do {
if (threadIsRun && ((new Date().getTime() - threadDate.getTime()) / 1000) > 5) {
try {
if (threadIsRun) {
threadIsRun = false;
}
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex);
}
threadIsRun = false;
startThread();
}
sleep(1000 * 60);
} while (true);
}
});
}
/**
* 多少毫秒后执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param run 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public static String setTimeout(Runnable run, int vTime) {
return timeout.Set(run, vTime);
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public static void clearTimeout(String flag) {
timeout.remove(flag);
}
/**
* 清除需要执行的任务
*
* @param run 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public static void clearTimeout(Runnable run) {
timeout.remove(run);
}
/**
* 每隔多少毫秒执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param run 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public static String setInterval(Runnable run, int vTime) {
return interval.Set(run, vTime);
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public static void clearInterval(String flag) {
interval.remove(flag);
}
/**
* 清除需要执行的任务
*
* @param run 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public static void clearInterval(Runnable run) {
interval.remove(run);
}
/**
* 沉睡
*
* @param mills 时间(毫秒)
*/
public static void sleep(int mills) {
try {
Thread.sleep(mills);
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex, mills);
}
}
/**
* 执行对象并且处理异常
*
* @param run 需要执行的对象
*/
public static void executeCatch(Runnable run) {
try {
run.run();
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex, null);
}
}
/**
* 需要执行的线程
*
* @param run
*/
public static void runThread(final Runnable run) {
_ExecuteService.execute(new Runnable() {
@Override
public void run() {
executeCatch(run);
}
});
}
/**
* 循环执行事务,直到停止执行
*
* @param run
*/
public static void runThread(final RunInterval run) {
runThread(new Runnable() {
public void run() {
while (!run.isBreak()) {
try {
run.getCode().run();
} catch (Exception ex) {
ExceptionHelper.handleException(ThreadHelper.class, ex);
}
sleep(run.getTime());
}
}
});
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment