java.util.timer类的具体实现问题

soar_king 2004-12-29 03:22:42
最近在学习java api文档的timer类时,有些疑惑,还请众高手指教。

timer.schedule(TimerTask1, seconds*1000);
timer.schedule(TimerTask2, seconds*1000);
假如我一个方法内有以上两条语句,请问这两条语句的执行顺序具体是怎样的?是两个task并发执行,还是只有task1运行完一次后,task2才接着运行?
从api的文档的介绍上看,timer同一时间只能调度一个task,当延迟时间小于task的运行时间时还会引起阻塞。由此看来,只有task1完成后,task2才能运行。但是timertask类是实现了runable接口的,这样的话,task在运行的时候是作为线程来运行的,那为何只有task1完成后task2才能开始运行呢?此乃疑惑一。我猜想timer的调度功能可能是这样实现的:timer的后台线程首先调用task1,然后暂停,直到收到task1完成的信息后才重新运行,并调用task2。不过如果这样,那么系统同时就应该只有两个线程,一个是timer的后台调度线程,一个是task1或task2运行时产生的线程。而我却看到有3个线程。不知这是怎么回事?此乃疑惑二。
以上均为我对timer类实现过程的揣测,如有何谬误实属正常,还请众高手指点迷津。
另外,在java Tutorial中提到了四种终止timer thread的方法,本人愚钝,看的不是十分明白,也请大家多多赐教。
...全文
689 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
soar_king 2005-01-25
  • 打赏
  • 举报
回复
谢谢
treeroot 2005-01-22
  • 打赏
  • 举报
回复
一塌糊涂!
调用wait方法要先获得同步锁,否则就有上面的异常
sychronized(this){
//
this.wait(xx);
}
另外如果需要保证逻辑上的顺序,只要合成为一个task就行了
示例代码
compositeTask extends TimerTask{
public void run(){
Thread task1=new Thread(new Task1());
Thread task2=new Thread(new Task2());
task1.start();
task1.join();//保证task1,结束task2才开始
task2.start();
}
}



soar_king 2005-01-22
  • 打赏
  • 举报
回复
就没有人来说一下吗?失望
ymm 2005-01-04
  • 打赏
  • 举报
回复
关注一下
soar_king 2005-01-04
  • 打赏
  • 举报
回复
顶一下,谁来详细说说这个问题啊
soar_king 2004-12-30
  • 打赏
  • 举报
回复
to liounzhou(潇潇夜雨) :"TimerTask1被覆盖了"是什么意思?不明白

我自己写了个测试,发现又有矛盾了
public class Reminder {
Timer timer;

public Reminder(int delay,int seconds,String test) {
timer = new Timer();
RemindTask task = new RemindTask();
task.setTest(test);
timer.schedule(task,delay,seconds*1000);
}

class RemindTask extends TimerTask {
private String test;
public void run() {
System.out.println(test);
}

public void setTest(String test) {
this.test = test;
}
}

public static void main(String args[]) {
System.out.println("About to schedule task.");
new Reminder(1000*5,1,"task 111");
new Reminder(1000*1,1,"task 222");
System.out.println("Task scheduled.");
}
}

得到输出:About to schedule task.
Task scheduled.
task 222
task 222
task 222
task 222
task 111
task 222
task 111
task 222
task 111
这样看来task是作为独立线程运行的,而且timer调度的时候是并发的。那“timer同一时间只能调度一个task”就有点疑问了。而当task1发生阻塞时,task2能否正常运行这个问题我还不知道如何测试,因为我不知道如何正确的使task1阻塞。我曾经尝试使用以下方法,却得到异常
public class Reminder {
Timer timer;

public Reminder(int delay,int seconds,String test,long time) {
timer = new Timer();
RemindTask task = new RemindTask();
task.setTest(test);
task.setTime(time);
timer.schedule(task,delay,seconds*1000);
}

class RemindTask extends TimerTask {
private String test;
private long time;
public void run() {
try {
this.wait(time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(test);
}

public void setTest(String test) {
this.test = test;
}
public void setTime(long time) {
this.time = time;
}
}

public static void main(String args[]) {
System.out.println("About to schedule task.");
new Reminder(1000*5,1,"task 111",500);
new Reminder(1000*1,1,"task 222",0);
System.out.println("Task scheduled.");
}
}
输出:About to schedule task.
Task scheduled.
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at Reminder$RemindTask.run(Reminder.java:34)
at java.util.TimerThread.mainLoop(Timer.java:432)
at java.util.TimerThread.run(Timer.java:382)
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at Reminder$RemindTask.run(Reminder.java:34)
at java.util.TimerThread.mainLoop(Timer.java:432)
at java.util.TimerThread.run(Timer.java:382)
还请各位说说为何会出现这种情况
liounzhou 2004-12-30
  • 打赏
  • 举报
回复
timer.schedule(TimerTask1, seconds*1000);
timer.schedule(TimerTask2, seconds*1000);
我觉得应该要看第一个seconds*1000的时间长度,如果足够长,会做完TimerTask1才会继续做TimerTask2.如果时间太短,会直接跳过TimerTask1而去做TimerTask2,因为TimerTask1被覆盖了.如果是在执行TimerTask1的时候,TimerTask2开始执行,则程序会报错.
soar_king 2004-12-30
  • 打赏
  • 举报
回复
那如果两个任务有逻辑上的顺序的话岂不是会出错
fdm_sea 2004-12-30
  • 打赏
  • 举报
回复
当然有了,只是你现在还没想到罢了 ^_^
比如可以重复检测某个事件啊之类的
soar_king 2004-12-30
  • 打赏
  • 举报
回复
不解,执行顺序无法预测的话那这个方法还有何意义
yaoyuan_harbin 2004-12-30
  • 打赏
  • 举报
回复
同意,执行顺序没有办法预测。
fdm_sea 2004-12-30
  • 打赏
  • 举报
回复
new Timer时是创建了新的线程,而执行顺序是由操作系统决定没法预测的
86867651 2004-12-29
  • 打赏
  • 举报
回复
我想应该是先运行 task1 然后才运行 task2 .

关注下
doni 2004-12-29
  • 打赏
  • 举报
回复
关注

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧