我做了一个自动执行的程序,用到了schedule(Timer task,Date firstTime,long period)函数,我设置的period为24*60*60(一天),单击"设置"按钮这个程序现在可以运行,但现在遇到一个情况,假如我设置好了时间,单击了"设置"按钮,在程序还没到指定的时间时我想停掉他,重新定时.我在"取消"的按钮事件中掉用了Timer.cancle();,但点取消时会抛出Exception,Task already scheduled or cancelled
我现在的疑问是为什么只能定时一次,怎么样可以取消上次的定时执行,重新定时

解决方案 »

  1.   

    public class ClockTimer{
        private static ClockTimer clockTimer = new ClockTimer();
        private static Timer timer = null;    private ClockTimer() {    }    static synchronized public ClockTimer getInstance() {        if (clockTimer == null) {
                clockTimer = new ClockTimer();
            }        return ClockTimer;
        }    public void start(int millisecond) {        stop();        timer = new Timer();
            timer.schedule(new TimerTask() {            public void run() {                // do your task
                }
            }, millisecond);
        }    public void stop() {        try {
                if (timer == null) {
                    return;
                }            timer.cancel();
            }
            catch (java.lang.IllegalStateException ex) {
                System.out.println(ex.getMessage());
            }
            finally {
                timer = null;
            }
        }
    }
      

  2.   

    我把代码贴出来大家看看吧1.AutoTime.javapublic class AutoTime {

    MainWindow mw;
    ProcessModel pm;

    SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat sim2 = new SimpleDateFormat("yyyy-MM-dd");    
    String timeText;         //存放输入的time(hh:mm:ss)

    String firstTime;
    String startTime;
    String endTime;
    Date start;
    Date end;
    Date first;
    long period = 86400000;
    Timer timer;
    Task task;
      /*pm.parseHtmlDoc(udate,changeURL(udate, url1, url2));
    排程多日运行时,用这个方法传递urlDate和urladdress,因为排程的日期在变,这个时候只需改变uDate,
    */
    public AutoTime(MainWindow mw, ProcessModel pm){
    this.mw = mw;
    this.pm = pm;
    task = new Task(this,mw.chol,mw,pm);

    }

    public void getStartDate(String s){
    if(!s.equals("")){  
    startTime = s;        //得到开始日期 }
    }
    public void getEndDate(String e){
    if(!e.equals("")){
    endTime = e;          //得到结束日期
    }
    }
    public void getTime(String time){
    timeText = time;
    }

    public void dealDate(){
    firstTime = startTime +" "+ timeText;          //得到第一次要运行的时间
    try {
    start = sim2.parse(startTime);    //日期格式
    end = sim2.parse(endTime);         
    first = sim1.parse(firstTime);

    } catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    task.getDate(start);

    }

    //compare firstTime with today
    public boolean compare(Date dateToday){

    int num = first.compareTo(mw.dateToday);
    if(num<0){
    return  false;
    }
    else{
    return true;
    }
    }

    public void start(){
    timer = new Timer();
    timer.schedule(task,first,period);
    }
    public void stop(){

    if(timer == null){
    return;
    }
    timer.cancel();

    }}2 Task
    public class Task extends TimerTask{

    private MainWindow mw;
    private ProcessModel pm;
    private AutoTime autoTime;
    private CheckHoliday chol;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    private SimpleDateFormat sdf1 = new SimpleDateFormat("yyMMdd");
    private String linkDate;
    private Date temD;   //日期格式为yyyyMMdd

    public Task(AutoTime autoTime ,CheckHoliday chol, MainWindow mw, ProcessModel pm){
    this.autoTime = autoTime;
    this.chol = chol;
    this.mw = mw;
    this.pm = pm;
    }

    public void getDate(Date s){
    temD = s;
    }


    public void run(){
    if(mw.cancleFlag == 1){
    autoTime.timer.cancel();
    }
    //while(autoTime.start.before(autoTime.end)||autoTime.start.equals(autoTime.end)){
    if(autoTime.start.before(autoTime.end)||autoTime.start.equals(autoTime.end)){
    if(chol.isWorkDay(temD)){
    pm.parseHtmlDoc(sdf.format(temD),mw.changeURL(sdf.format(temD), mw.url1, mw.url2));
             pm.upLoad();
             //break;
    }
    temD = getNextDay(temD);
    }
    }


    private Date getNextDay(Date temD){
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTime(temD);
    calendar.add(GregorianCalendar.DATE, 1);
    temD = calendar.getTime();

    return temD;
    }
    }这个程序要连续执行,每天运行一次,界面的代码我没贴出来
    我现在就是想假如已经为程序定时了,但还没有执行的时候我想取消它,然后重新定时
      

  3.   

    界面的代码和处理的代码都没有贴,大家看看吧,
    第一次定时的时候,设置了开始 运行的时间,结束的时间,然后点"设置"按钮,已经启动定时器了,但我想取消这次定时,重新安排Exception:
    Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Task already scheduled or cancelled
      

  4.   

    OPEN SOURCE上有个开源的组件  QUARTZ,能满足你的要求
    Task already scheduled or cancelled 看下你的Task 线程是不是已经中断了,你又去中断了一次
      

  5.   

    先stop了quartz功能适合一些复杂的情况,LZ的单次触发不需要QUARTZ以前做过一个大型系统的定时模块,用的是QUARTZ,不过QUARTZ也有一个缺陷,他对每天不同小时的不同分钟情况无法在一个CRON中写出,必须写多个,也就导致多个线程。对定时器的控制就相当麻烦了
      

  6.   

    是这样的。每一个TimerTask对象只能被指认执行一次任务。所以要想在运行就必须重新建立一个TimerTask对象