1.创建MyTimerTask类,定义两个变量,运行时间runAtTime和任务target;
2.构造方法中初始化时间和任务,时间为传入时间参数+系统当前时间;
3.复写Comparable比较执行时间的优先级;
private static class MyTimerTask implements Comparable<MyTimerTask>{
long runAtTime;
Runnable target;
public MyTimerTask(long delay, Runnable target){
this.runAtTime = System.currentTimeMillis()+delay;
this.target = target;
}
@Override
public int compareTo(MyTimerTask o) {
if(o.runAtTime < runAtTime){
return 1;
}else if(o.runAtTime == runAtTime){
return 0;
}else {
return -1;
}
}
}
4.定义一个阻塞队列(优先级队列);
5.写一个工作线程Worker;
6.工作线程中比较线程运行时间和系统当前时间大小,若系统时间小,说明还未到执行时间,将任务放回优先级队列,并等待所差时间,否则时间到执行任务;
private PriorityBlockingQueue<MyTimerTask> queue = new PriorityBlockingQueue<>();
Thread worker = new Worker();
private class Worker extends Thread{
@Override
public void run() {
while (true){
try {
MyTimerTask task = queue.take();
if(task.runAtTime <= System.currentTimeMillis()){
task.target.run();
}else {
queue.put(task);
synchronized (this) {
wait(task.runAtTime - System.currentTimeMillis());
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
7.重写主线程构造方法,启动worker线程;
8.写schedule方法参数为任务target和等待时间delay,内容为创建一个MyTimerTask对象传参,并将该对象放入优先级队列中;并且唤醒一个等待中线程,
9.在main方法中写一个任务target,创建一个主类对象,调用schedule方法传入target和等待时间;
注:如果不重写compareTo方法会无法比较,造成运行时异常;
MyTimer(){
worker.start();
}
public void schedule(Runnable target, long delay){
MyTimerTask task = new MyTimerTask(delay, target);
queue.put(task);
synchronized (this){
notify();
}
}
public static void main(String[] args) {
Runnable target = new Runnable() {
@Override
public void run() {
System.out.println("五秒后");
}
};
MyTimer timer = new MyTimer();
timer.schedule(target, 5000);
}
}
完成代码如下:
import java.util.concurrent.PriorityBlockingQueue;
public class MyTimer {
private static class MyTimerTask implements Comparable<MyTimerTask>{
long runAtTime;
Runnable target;
public MyTimerTask(long delay, Runnable target){
this.runAtTime = System.currentTimeMillis()+delay;
this.target = target;
}
@Override
public int compareTo(MyTimerTask o) {
if(o.runAtTime < runAtTime){
return 1;
}else if(o.runAtTime == runAtTime){
return 0;
}else {
return -1;
}
}
}
private PriorityBlockingQueue<MyTimerTask> queue = new PriorityBlockingQueue<>();
Thread worker = new Worker();
private class Worker extends Thread{
@Override
public void run() {
while (true){
try {
MyTimerTask task = queue.take();
if(task.runAtTime <= System.currentTimeMillis()){
task.target.run();
}else {
queue.put(task);
Thread.sleep(task.runAtTime-System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
MyTimer(){
worker.start();
}
public void schedule(Runnable target, long delay){
MyTimerTask task = new MyTimerTask(delay, target);
queue.put(task);
}
public static void main(String[] args) {
Runnable target = new Runnable() {
@Override
public void run() {
System.out.println("五秒后");
}
};
MyTimer timer = new MyTimer();
timer.schedule(target, 5000);
}
}