1. Timer的了解和使用
public class ThreadDemo26 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("1000");
}
},1000);
}
}
运行结果:
这里我们需要 定义一个timer ,通过timer.schedule() TimerTask里面实现了内部类,来实现run方法,并且可以把时间少的先进行执行,并且把所有的消息队列执行完,该线程还是不会结束的,这个属于前端后台。
通过上述的简单描述我们就可以让我们自己实现Timer 的功能有一个简单的了解,接下来让我们来一起实现MyTimer吧!!!
2. MyTimer的自己实现
2.1 Timer 中TimerTask的实现
class MyTimerTask implements Comparable<MyTimerTask>{
// 优先队列里的泛型对象
// 来实现Runnable接口
private Runnable runnable = null;
// 时间
private long time = 0;
public long getTime(){
return time;
}
public MyTimerTask(Runnable runnable,long delay){
this.runnable = runnable;
this.time = System.currentTimeMillis() + delay;
}
public void run(){
runnable.run();
}
// 因为要实现优先队列所以需要比较方法
@Override
public int compareTo(MyTimerTask o) {
return (int) (this.time - o.time);
}
}
这里我们实现了MyTimerTask 1. 我们实现了Comparable的包 因为在后面会有一个消息队列(它是一个优先队列),需要把时间小的完成先执行 2. 因为在系统时间是以时间戳来进行得到的大小,所以我们要用long 3. 而Runnable是来实现run的方法的。
2.2 MyTimer 的实现
class MyTimer{
// 创建线程
Thread t = null;
// 创建一个锁对象
private Object locker = new Object();
// 创建一个类型为MyTimerTask的优先级队列
private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();
// 自己实现schedule的方法
public void schedule(Runnable runnable,long delay){
// 关于写类似的操作是 要加锁以免不必要的麻烦
synchronized (locker){
MyTimerTask task = new MyTimerTask(runnable,delay);
queue.offer(task);
locker.notify();
}
}
// 构造方法
public MyTimer(){
// 给t赋值
t = new Thread(() -> {
while(true){
synchronized (locker){
try {
while(queue.isEmpty()){
locker.wait();
}
long curTime = System.currentTimeMillis();
MyTimerTask task = queue.peek();
if(task.getTime() <= curTime){
queue.poll();
task.run();
} else {
locker.wait(task.getTime() - curTime);
}
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
});
t.start();
}
}
这里我们需要一个线程,一个Object的对象,一个priorityQueue的队列,并且我们需要完成schedule的方法,这里因为该方法有写的操作,会出现线程安全问题所以要对该方法加锁,还有在MyTimer构造方法中,因为不确定这个数是否要出队列,所以我们使用了 peek()方法,如果后续达到了要求 在if语句里面poll等相关操作。
其实,在这里考虑的也很多,像线程安全问题就是很重要了,要非常小心加锁,加的问题因为一个位置加的不对,可能会引起很大的不同。