上一篇讲了传统的线程技术,这一篇来回顾传统定时器
// //第一种定时器是多少时间以后执行
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("bombing");
}
}, 10000);
while (true) {
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//第二种定时器是多少时间以后执行,然后每隔多久再去执行
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("bombing");
}
}, 4000, 2000);
while (true) {
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* 第三种来说下一种特殊的定时器:一种轮换式的定时器,这种定时器是多少时间以后去执行
* 然后隔一定时间(比如说2s)执行,再隔一定时间(比如说4s)执行,再每隔隔一定时间(还是2s)
* 再隔一定时间(还是4s)执行,如此循环往复的执行下去
*/
//下面是一种错误的思想
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
new Timer().schedule(this, 4000);
}
}, 2000);
while (true) {
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
}
以上控制台会打印:
41
42
Exception in thread "Timer-0" java.lang.IllegalStateException:Task already scheduled or cancelled
at java.util.Timer.sched(Unknown Source)
at java.util.Timer.schedule(Unknown Source)
at com.iever.thread.TraditionalTimerTest$1.run(TraditionalTimerTest.java:60)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
43
绿色的文字已经可以来说明原因了:我们这样来解释,好比有一颗炸弹2s后爆炸,你又让他4后再次爆炸,
原来的炸弹已经在前一次爆炸中炸成灰,后面4s又怎么可能会爆炸呢,所以解决这个问题的方法就是新建一个
类继承自TimerTask,下面是实现代码
public class TraditionalTimerTest {
private static int count = 0;
public static void main(String[] args) {
/**
* 方法一:设一个静态变量来保存奇数次或偶数次的变化
*/
class MyTimerTask extends TimerTask{
@Override
public void run() {
count = (count + 1)%2;
new Timer().schedule(new MyTimerTask(), 2000+2000*count);
// TODO Auto-generated method stub
System.out.println("bombing");
}
}
new Timer().schedule(new MyTimerTask(), 2000);
while (true) {
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
}
控制台打印如下:
0
1
bombing
2
3
4
5
bombing
6
7
bombing
8
9
10
11
bombing
12
13
bombing
方法二:根据时间的不同写一个有关时间的构造方法
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TraditionalTimerTest {
public static void main(String[] args) {
class MyTimerTask extends TimerTask{
//因为两个task的时间不同,所以写一个构造方法
private int sceond;
public MyTimerTask(int sceond){
this.sceond = sceond;
}
@Override
public void run() {
System.out.println("bombing");
if(sceond == 2000){
sceond = 4000;
}else{
sceond = 2000;
}
new Timer().schedule(new MyTimerTask(sceond), sceond);
}
}
new Timer().schedule(new MyTimerTask(2000), 2000);
while (true) {
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
打印如下:
10
11
bombing
12
13
14
15
bombing
16
17
bombing