自定义创建定时任务

项目框架:springboot

@Component
public class TestTimeTask {
	
	private static Queue> queue = new LinkedBlockingDeque<>();
	
	@PostConstruct
	public void doMethod(){
		Thread t = new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true) {
					ThirdTuple one = queue.poll();
					if(one==null) {
						continue;
					}
					Date next =dealTime(one.first(),one.four());
					Runnable r = one.third();
					String name = one.second();
					long now = System.currentTimeMillis();
					if(next.getTime()==now) {
						Thread t = new Thread(r, "testTimeTask-"+name);
						t.start();
						System.out.println("执行定时任务:"+" 命名:"+name+" 下次执行时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(next));
						one.setFour(next);
					}
					queue.offer(one);
				}
				
			}
		});
		t.setDaemon(true);
		t.start();
	}
	
	public void addThreadQueue(Runnable r,String pattern,String name) {
		if(!checkPattern(pattern)) {
			return;
		}
		ThirdTuple tuple = new ThirdTuple(pattern, name,r,new Date());
		queue.offer(tuple);
	}
	
	public Date dealTime(String pattern,Date time) {
		CronSequenceGenerator cqg = new CronSequenceGenerator(pattern);
		Date next = cqg.next(time);
		return next;
	}
	
	public Boolean checkPattern(String pattern) {
		return CronSequenceGenerator.isValidExpression(pattern);
	}
	
	public Queue> returnQueue() {
		return queue;
	}
	
}

简单类(建了一个四元的元组类,A代表定时时间间隔跟@schedule的cron是一样的,"0/10 * * * * *?"的格式,B代表线程名称,C代表要启动的类对象该类需要实现Runnable接口,D代表开始执行的时间)

public class ThirdTuple {

		
	private A first;
	private B second;
	private C third;
	private D four;
	
	public ThirdTuple(A a,B b,C c,D d) {
		this.first=a;
		this.second=b;
		this.third = c;
		this.four =d;
	}

	
	public A first() {
		return first;
	}


	public B second() {
		return second;
	}
	
	public C third() {
		return third;
	}
	
	public D four() {
		return four;
	}
	
	public void setFour(D d) {
		this.four=d;
	}

}

这个只是个测试类

public class Task implements Runnable {

	@Override
	public void run() {
		System.out.println("这是一个线程");
	}

}

处理方式:
1.在项目启动时,采用@PostConstruct 来使容器运行时就加载这个方法,然后在方法中启动一个线程作为守护线程(项目停止则守护线程死亡)
2.在守护线程中采用死循环对维护的静态队列进行操作(此处有个问题,可以采用其他方式来维护这个线程队列),
3.从队列中取出一个对象,然后获取时间,通过dealTime来获取下次执行的时间,判断下次执行时间是否等于当前时间,是则执行,执行后将对象的four属性更新为此次执行时间,然后再加入到队列中,

这样可以简单的实现用户自主设置定时任务,但此方法我也考虑过 多有不足:
1.无法准确的获取当前有哪些线程队列
2.守护线程只有一个,对队列操作是逐个,如果队列中有2个任务时间是一样的,可能会导致一个任务得到执行,当执行另一个任务时,当前时间已大于该任务的执行时间(也许也可以next.getTime()<=now来改善)

如有其他好方法欢迎大家讨论下,毕竟在下只是菜鸟一枚!!!!!!

你可能感兴趣的:(定时任务处理)