自己编写一个定时器工具叫做didadida工具吧。
需求:每隔几秒(delay)后,执行我提供的一个任务(task)。
基础版
这是一个抽象类,每隔几秒需要执行的内容是要用户自己完成的。
public abstract class simple implements Runnable{
private static final int DEAULT_DELAY = 1000;
private volatile boolean goon;
private Object lock = new Object();
private int delay;
public simple() {
this(DEAULT_DELAY);
}
public simple(int delay) {
this.delay = delay;
goon = false;
}
public void setDealy(int delay) {
this.delay = delay;
}
public void start() {
if(goon == true) {
return;
}
new Thread(this).start();
goon = true;
}
public void stop() {
if(goon == false) {
return;
}
goon = false;
}
//任务
public abstract void doSomething();
@Override
public void run() {
while(goon) {
//这里其实是单线程执行的,并没有多线程问题。
//但是我选用了object.wait()方法,必须要在同步代码块中。
//至于为什么不用Thread.sleep()。因为sleep比较耗cpu。
synchronized(lock) {
try {
//当前线程睡眠delay毫秒之后执行dosomething
lock.wait(delay);
doSomething();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
测试代码
public static void main(String[] agrs) {
simple simpleDida = new simple(400) {
@Override
public void doing() {
try {
Thread.sleep(100);
System.out.println(System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
simpleDida.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
simpleDida.stop();
}
只打印了10次,因为是单线程执行,doSomething方法和didadida计时器方法是同一个线程,所以soSomething方法也会占用时间。上述代码执行一个轮回就是400+100毫秒。
最简单的解决方案就是soSomething用一个线程来跑。
下面进阶版
进阶版
这个版本的定时器,由于doSomething();是另一个线程再跑,所以执行这个方法时,不会影响定时器的计时。
@Override
public void run() {
while(goon) {
synchronized(lock) {
try {
lock.wait(delay);
new something();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class something implements Runnable{
public something() {
new Thread(this).start();
}
@Override
public void run() {
doSomething();
}
}