2009-06-25 39 views
17

Tôi đang cố gắng sử dụng bộ hẹn giờ để lên lịch sự kiện định kỳ trong một ứng dụng. Tuy nhiên, tôi muốn có thể điều chỉnh khoảng thời gian mà sự kiện xảy ra trong thời gian thực (theo đầu vào của người dùng).Java Timer

Ví dụ:

public class HelperTimer extends TimerTask 
{ 
    private Timer timer; 
    //Default of 15 second between updates 
    private int secondsToDelay = 15; 

    public void setPeriod(int seconds) 
    { 
     this.secondsToDelay = seconds; 
     long delay = 1000; // 1 second 
     long period = 1000*secondsToDelay; // seconds 
     if (timer != null) 
     { 
      timer.cancel(); 
     } 
     System.out.println(timer); 
     timer = new Timer(); 
     System.out.println(timer); 
     timer.schedule(this, delay, period); 
    } 
    public int getPeriod() 
    { 
     return this.secondsToDelay; 
    } 
} 

Sau đó tôi bắt đầu một trường hợp mới của lớp này và gọi hàm thời gian đề ra. Tuy nhiên, khi tôi làm điều đó, tôi nhận được một ngoại lệ bất hợp pháp của tiểu bang. Bạn có thể thấy System.out.println (timer); trong đó bởi vì tôi đang kiểm tra và chắc chắn đủ, chúng là hai bộ tính giờ khác nhau ... vậy tại sao tôi nhận được một IllegalStateException khi tôi cố gắng chạy một cuộc gọi lịch biểu trên một phiên bản Timer mới!?!?!?!

[email protected] 
[email protected] 
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Task already scheduled or cancelled 
    at java.util.Timer.sched(Unknown Source) 
    at java.util.Timer.schedule(Unknown Source) 
    at HelperTimer.setPeriod(HelperTimer.java:38) 

Trả lời

16

Bạn không thể sử dụng lại TimerTask khi bạn đang làm ở đây.

porition liên quan của Timer:

private void sched(TimerTask task, long time, long period) { 
    if (time < 0) 
     throw new IllegalArgumentException("Illegal execution time."); 

    synchronized(queue) { 
     if (!thread.newTasksMayBeScheduled) 
      throw new IllegalStateException("Timer already cancelled."); 

     synchronized(task.lock) { 
      //Right here's your problem. 
      // state is package-private, declared in TimerTask 
      if (task.state != TimerTask.VIRGIN) 
       throw new IllegalStateException(
        "Task already scheduled or cancelled"); 
      task.nextExecutionTime = time; 
      task.period = period; 
      task.state = TimerTask.SCHEDULED; 
     } 

     queue.add(task); 
     if (queue.getMin() == task) 
      queue.notify(); 
    } 
} 

Bạn sẽ cần phải cấu trúc lại mã của bạn để bạn tạo ra một TimerTask mới, chứ không phải là tái sử dụng một.

+1

Như Kevin đã nói, bạn đang gọi "timer.schedule (này, trì hoãn, dấu chấm)" với cùng "điều này" mỗi lần. TimerTask không có nghĩa là được cung cấp cho nhiều bộ hẹn giờ khác nhau. Mỗi thể hiện TimerTask có nghĩa là được lên lịch chính xác một lần. – Eddie

+1

Cảm ơn, điều đó hoàn toàn không xuất hiện trong tài liệu, và ngay sau khi tôi chuyển sang tạo TimerTask mới, mọi thứ đều theo kế hoạch .. – Zak

+2

Đặc tả trạng thái lịch biểu: @throws IllegalStateException nếu tác vụ đã được lên lịch hoặc hủy, hẹn giờ đã bị hủy hoặc bộ hẹn giờ bị chấm dứt. Tác vụ đã được lên lịch trong Bộ hẹn giờ trước đó, do đó ngoại lệ bị ném. – notnoop

4

Có vẻ lạ khi tôi có TimerTask với Bộ hẹn giờ riêng bên trong nó. Thiết kế xấu. Tôi hoàn toàn tách rời cả hai và thực hiện TimerTask được đưa đến Timer, và đặt tất cả logic đó về việc không quan trọng với khoảng thời gian bên trong một lớp khác cung cấp một giao diện để làm như vậy. Hãy để lớp đó khởi tạo Timer và TimerTask và gửi chúng đi để thực hiện công việc của chúng.

0
import java.util.*; 
    class TimeSetting 
    { 
    public static void main(String[] args) 
    { 
    Timer t = new Timer(); 
    TimerTask time = new TimerTask() 
    { 
    public void run() 
    { 
    System.out.println("Executed......"); 
    } 
    }; 
    t.scheduleAtFixedRate(time, 4000, 3000); 
    // The task will be started after 4 secs and 
    // for every 3 seconds the task will be continuously executed..... 
    } 
    } 
+0

Lần đầu tiên, "Thực thi ...." sẽ được in sau 4 giây trì hoãn .. Sau đó, nó sẽ được in liên tục trong mỗi 3 giây. – deeban

Các vấn đề liên quan