滴答滴答改良——丑九怪
- 基于上次的滴答滴答(定时器),这里给出改良版本,但是有回报必然有代价,这次的情况听我娓娓道来。
- 我上次所写的定时器中有个缺点:那就是我们设定的扫描时间,要比doSomething的时间长一点,这样当下一轮notify时,才可以继续进行下一次扫描。也就是对时间有要求。
- 以下是我的解决想法:结合代码来看,上次的滴答滴答每过一段时间,都唤醒一次,然后执行一次,所执行的都是同一个线程在跑,那么可不可以实现每次唤醒,都生成一个新的线程去跑我们的doSomething方法,我已经实现了,以下是代码。
// 这是个内部类,在被计时器唤醒之后,会创建一个新的内部类:worker
class Dida implements Runnable {
public Dida() {
creatNewThread();
}
public void creatNewThread() {
new Thread(this).start();
}
@Override
public void run() {
while (goon) {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
new Worker();
}
}
}
下面是内部类Worker,这个类就专门负责doSomething方法的执行
class Worker implements Runnable {
public Worker() {
new Thread(this).start();
}
@Override
public void run() {
doSomething();
}
}
- 以下是测试类以及测试结果
AnotherDida didadida = new AnotherDida() {
@Override
public void doSomething() {
for (int i = 0; i < 10000000; i++) { // 这个空循环用来延长doSomething的执行时间
}
System.out.println("当前时间" + System.currentTimeMillis());
}
@Override
public void beforeDoSomething() {
}
@Override
public void afterDoSomething() {
}
};
didadida.setDelayTime(1000); // 设定的扫描时间为1000毫秒
didadida.startUp();
上面的结果已经验证了这个方法的正确性,但是这个方法也有弊端。
可以看代码,每次等等待时间一到,立刻产生一个全新的线程,这样形成的扫描就像海浪一样,层叠起来,但是当doSomething的时间很长,而扫描间隔又非常短的时候,就会出现同时存在很多线程的情况。