1、队列工具类
import java.lang.reflect.Method;
import java.util.concurrent.DelayQueue;
public class DelayExecUtil {
/**
* 延期执行队列
*/
private final static DelayQueue<DelayObject> queue=new DelayQueue<>();
/**
* 控制只允许启动一次
*/
private static boolean execFlag=false;
/**
* 添加延期执行对象
* @param delayObject
*/
public static void add(DelayObject delayObject){
queue.add(delayObject);
//添加元素后就开始执行
execute();
}
public static void remove(DelayObject delayObject){
queue.remove(delayObject);
}
private static void execute(){
if(execFlag){
return;
}
synchronized (DelayExecUtil.class){
if(execFlag){
return;
}
execFlag=true;
new Thread(()->{
while(true){
try {
DelayObject delay = queue.take();
Class<?> aClass = delay.getCallBackInstance().getClass();
Object params = delay.getParams();
Method method;
if (null != params) {
method = aClass.getMethod(delay.getMethodName(), params.getClass());
method.invoke(delay.getCallBackInstance(), params);
} else {
method = aClass.getMethod(delay.getMethodName());
method.invoke(delay.getCallBackInstance());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
2、延迟执行对象
import org.apache.commons.lang.StringUtils;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* 延期执行对象
*/
public class DelayObject implements Delayed {
/**
* 唯一id
*/
private String uuid;
/**
* 延期执行时间 到达该时间后,当前任务执行
*/
private Date executeTime;
/**
* 方法参数
*/
private Object params;
/**
* 回调实例
*/
private Object callBackInstance;
/**
* 回调方法名
*/
private String methodName;
public DelayObject(String uuid) {
if(StringUtils.isEmpty(uuid)){
throw new IllegalArgumentException("extendObject or extendObject.id is null");
}
this.uuid = uuid;
}
public Date getExecuteTime() {
return executeTime;
}
public void setExecuteTime(Date executeTime) {
this.executeTime = executeTime;
}
public Object getCallBackInstance() {
return callBackInstance;
}
public void setCallBackInstance(Object callBackInstance) {
this.callBackInstance = callBackInstance;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Object getParams() {
return params;
}
public void setParams(Object params) {
this.params = params;
}
/**
* Returns the remaining delay associated with this object, in the
* given time unit.
*
* @param unit the time unit
* @return the remaining delay; zero or negative values indicate
* that the delay has already elapsed
*/
@Override
public long getDelay(TimeUnit unit) {
return this.executeTime.getTime() - System.currentTimeMillis();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DelayObject that = (DelayObject) o;
return Objects.equals(uuid, that.uuid);
}
/**
* Compares this object with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
* <p>
* <p>The implementor must ensure <tt>sgn(x.compareTo(y)) ==
* -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>. (This
* implies that <tt>x.compareTo(y)</tt> must throw an exception iff
* <tt>y.compareTo(x)</tt> throws an exception.)
* <p>
* <p>The implementor must also ensure that the relation is transitive:
* <tt>(x.compareTo(y)>0 && y.compareTo(z)>0)</tt> implies
* <tt>x.compareTo(z)>0</tt>.
* <p>
* <p>Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt>
* implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for
* all <tt>z</tt>.
* <p>
* <p>It is strongly recommended, but <i>not</i> strictly required that
* <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>. Generally speaking, any
* class that implements the <tt>Comparable</tt> interface and violates
* this condition should clearly indicate this fact. The recommended
* language is "Note: this class has a natural ordering that is
* inconsistent with equals."
* <p>
* <p>In the foregoing description, the notation
* <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
* <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
* <tt>0</tt>, or <tt>1</tt> according to whether the value of
* <i>expression</i> is negative, zero or positive.
*
* @param o the object to be compared.
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
* @throws NullPointerException if the specified object is null
* @throws ClassCastException if the specified object's type prevents it
* from being compared to this object.
*/
@Override
public int compareTo(Delayed o) {
int result = this.getExecuteTime().compareTo(((DelayObject) o).getExecuteTime());
return result;
}
}