TimerTask停止所有其他执行

时间:2016-08-07 13:15:58

标签: java multithreading timer

我有一个程序启动计时器,然后在停止之前每秒重复一次代码。发生的事情是它不会阻止来自main的执行。我假设它只是一个与它一起运行的线程,但是从查看帖子我仍然不确定如何暂时停止它。

final class DogDoor{
  private static DogDoor dogDoor;
  private boolean open;

  private DogDoor(){
    open=false;
  }

  public static synchronized DogDoor getDogDoor(){
    if(dogDoor==null){
      dogDoor=new DogDoor();
    }
    return dogDoor;
  }

  public void activate(){
    open=!open;
    System.out.println(open? "Door is open!": "Door is closed!");
    if(open){
      autoClose();
    }
  }
  public void autoClose(){
    System.out.print("Door closing in 5 seconds . . .");

    //right before it starts the timer and task
    timer();

    //then resume here after the timer completes
    activate();
  }
  public void timer(){
    new java.util.Timer().scheduleAtFixedRate(
      new java.util.TimerTask(){

        //Prefer to stop until this completes
        int s=5;
        @Override
        public void run(){
          System.out.print(" .");
          if((s--)==0){
            cancel();
          }
        }
      }, 0, 1000);
  }
}

final class Remote{
  private static Remote remote;
  private boolean windowsLocked;
  private int lockCode;

  public Remote(){
    windowsLocked=true;
    generateLockCode();
  }

  public static synchronized Remote getRemote(){
    if(remote==null){
      remote=new Remote();
    }
    return remote;
  }
  public String getLockCode(){
    return String.format("%03d", lockCode);
  }

  public boolean windowsLocked(){
    return windowsLocked;
  }
  public void generateLockCode(){
    lockCode=(int)(Math.random()*1000);
  }
  public void toggleDoor(){
    DogDoor.getDogDoor().activate();
  }
  public void fixWindows(){
    if(passCodeVerifier()){
      windowsLocked=!windowsLocked;
      System.out.println(windowsLocked? "Windows locked!": "Windows unlocked!");
    }
    else{
      System.out.println("Invalid passcode!");
    }
  }
  public boolean passCodeVerifier(){
    Scanner scanner=new Scanner(System.in);
    System.out.print("Enter three digit keypad code: ");
    return scanner.hasNext("^\\d{3}$") && Integer.parseInt(scanner.next())==(lockCode);
  }
}

public class DogDoorDemo{
  public static void main(String[] args){
    System.out.println("Dog door demo.");
    System.out.println();

    System.out.println(Remote.getRemote().getLockCode());
    Remote.getRemote().toggleDoor();

    //and finally resume here
    Remote.getRemote().fixWindows();
  }
}

1 个答案:

答案 0 :(得分:1)

如文档中所述,计时器是:

A facility for threads to schedule tasks for future execution in a **background thread**

这意味着使用TimerTask运行的程序的任何部分都将在与主程序运行的单独线程上运行,因此不会阻止在主线程上执行。

另一种解决方案是将线程休眠所需的秒数,如下所示(用这个替换你的timer()方法并捕获InterruptedException。):

void timer(int seconds)throws InterruptedException{
    for(int i = 0; i < seconds; i++){
        Thread.sleep(1000);
        //Output whatever message you want to appear every second. The variable 'i' will hold the current second in the countdown.
    }
}

用这个替换你的autoClose方法:

public void autoClose(){
    System.out.print("Door closing in 5 seconds . . .");

    //right before it starts the timer and task
    timer(5);

    //then resume here after the timer completes
    activate();
}

Thread#sleep会抛出InterruptedException,因此必须妥善处理。