java Timer

kouwenlong 2012-09-26 09:26:57
Timer timer = new Timer();
tt = new timertask(loginFrame);
Button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
try{
timer.schedule(tt, 0, 1000*60*loginFrame.getti());
}catch(IllegalStateException e){
tt.cancel();//取消任务
tt = new timertask(loginFrame);//创建新任务
timer.schedule(tt, 0, 1000*60*loginFrame.getti());
}
});


通过点击,产生一个任务。如果上一个任务没有完成,则结束上一个任务,并创建一个新的任务。上面的代码可以做到这样吗?
我通过多次调试发现,可能是不能,但自己不确定。想问下大牛,如果要实现我要的效果,代码需要修改吗?如果需要修改,错误出在哪里,该怎么改?或者能够设计这样一个实验,让我实现我要的效果。
...全文
268 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
oO临时工Oo 2012-09-29
  • 打赏
  • 举报
回复
package timer;

/**
* 一个单任务调度器
*/
public class SingleTask {

public MyThread thread = null;
private static int threadId = 0;

/**
* 设置一个新任务,并清除以前已存在的任务
* @param task
* @param delay
* @param period
*/
public void setTask( Runnable task,long delay, long period){
if(thread != null){
try{
thread.stop(); //多线程复杂环境下,要谨慎使用Thread.stop()
}catch(Exception e){
e.printStackTrace();
}

thread = null;
}

thread = new MyThread(task);
thread.setName("MyThread-" + threadId ++ );
thread.start();
}


class MyThread extends Thread{

private Object lock = new Object();
private long delay = 1000;
private long period = 0;
private Runnable task = null;

public MyThread(Runnable runnable){
this.task = runnable;
}

@Override
public void run(){
while(true){

if(task != null){
task.run();
}

//模拟Timer的周期执行
if(period <= 0){
break;
}
synchronized (lock) {
try {
lock.wait(period);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

//模拟Timer的延时启动
public void start(){
synchronized (lock) {
try {
lock.wait(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

this.start();
}
}
}



package timer;

/**
* 模拟使用者
*/
public class Test {
private static Runnable task1 = new Runnable() {
//任务一,无限制输出
@Override
public void run() {
while(true){
synchronized (task1) {
System.out.println("output from task1..");
}
}

}
};

private static Runnable task2 = new Runnable() {
//任务二,每秒输出一次打印
@Override
public void run() {
while(true){
synchronized (task2) {
System.out.println("===============output from task2..");
try {
task2.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
//break;
}
}
}
}
};

private static Object lock = new Object();
public static void main(String args[]){
SingleTask st = new SingleTask();
st.setTask(task1, 1000, 0);

//2秒后把任务1换成任务2
synchronized (lock) {
try {
lock.wait(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
st.setTask(task2, 1000, 0);
}
}

huntor 2012-09-27
  • 打赏
  • 举报
回复
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
class Task implements Runnable { ... } // class Task implements Callable {...}
final ScheduledFuture<?> future = scheduler.schedule(new Task(), 10, TimeUnit.SECONDS);
if(!future.isDone()){ future.cancel(); }
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
现在应该使用ScheduledExecutorService,提交一个任务返回一个Future。isDone检测是否完成、否则cancel
[/Quote]
+1
shenhua 2012-09-26
  • 打赏
  • 举报
回复
cancel()的确是退出任务。
你那样的做法貌似不科学啊。
Timer作为一个定时器,本来就是定时执行一次任务。针对你的需求其实应该可以在线程上操作。
比如,最基本的Timer定时器用法:

int time=1000;//定时时间1000ms
java.util.Timer timer = new java.util.Timer();
timer.schedule(new TimerTask() {
public void run() {
try
{
ts();//触发、调用方法,执行任务
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}, 0, time);
MiceRice 2012-09-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
别沉了,大家帮忙看下啊。
[/Quote]

你的主要问题是:
tt.cancel();//取消任务
这句话的作用理解错误,它不能取消已经执行中的任务,它只是取消任务调度而已。


取消任务需要你自己有处理机制,而不能靠调度器的cancel()。
MiceRice 2012-09-26
  • 打赏
  • 举报
回复
自己调用该函数来取消任务,比如:

public class MyTask extends TimerTask {
private volatile boolean run = true;
public void cancel() {
run = false;
super.cancel();
}
public void run() {
int cnt = 0;
while (run) {
System.out.println(cnt++);
try {
// 处理代码
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


Timer timer = new Timer();
tt = new MyTask();
timer.schedule(tt, 0, 1000*60*loginFrame.getti());
tt.cancel();


如果任务本身不是周期性的,那就会比较麻烦,要设法定期检查状态。
因为Java已经废除了 Thread.stop() 这种直接强行终止线程的做法了。
小豆芽的爱恋 2012-09-26
  • 打赏
  • 举报
回复
你这样写好像不对吧 timer.schedule()这个方法只是每个多长时间就重新执行一次操作 没有判断上一个是否结束的功能吧
huntor 2012-09-26
  • 打赏
  • 举报
回复
现在应该使用ScheduledExecutorService,提交一个任务返回一个Future。isDone检测是否完成、否则cancel
kouwenlong 2012-09-26
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

其实跟你开发多线程程序是类似的,结束任务要自己处理,一般也就是检测标志位,比如:

Java code
public class MyTask extends TimerTask {

private volatile boolean run = true;

public void stop() {
run ……
[/Quote]
没看明白,你这里怎么取消的任务?
kouwenlong 2012-09-26
  • 打赏
  • 举报
回复
别沉了,大家帮忙看下啊。
MiceRice 2012-09-26
  • 打赏
  • 举报
回复
其实跟你开发多线程程序是类似的,结束任务要自己处理,一般也就是检测标志位,比如:

    public class MyTask extends TimerTask {

private volatile boolean run = true;

public void stop() {
run = false;
}

@Override
public void run() {
int cnt = 0;
while (run) {
System.out.println(cnt++);
try {
// 处理代码
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
kouwenlong 2012-09-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 1 楼 的回复:
别沉了,大家帮忙看下啊。


你的主要问题是:
tt.cancel();//取消任务
这句话的作用理解错误,它不能取消已经执行中的任务,它只是取消任务调度而已。


取消任务需要你自己有处理机制,而不能靠调度器的cancel()。
[/Quote]
我需要的机制就是上一个任务没有完成,就结束,并创建一个新的任务。请问具体怎么实现,麻烦写下代码吧?

62,615

社区成员

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

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