2016-08-07 21 views
0

Ich habe ein Programm, das einen Timer startet und dann Code jede Sekunde wiederholt, bevor es stoppt. Was passiert, ist, dass es die Ausführung von main nicht stoppt. Ich gehe davon aus, dass es nur ein Thread ist, der damit einhergeht, aber wenn ich mir die Posts anschaue, bin ich mir immer noch nicht sicher, wie ich das vorübergehend stoppen kann.TimerTask stoppe alle anderen Ausführungen

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(); 
    } 
} 
+0

Es ist nicht ganz klar, was Ihre Frage ist. Was möchten Sie anhalten und wann? – rodit

+1

Ein Timer soll die Ausführung des aufrufenden Codes nicht stoppen - das ist einer der Hauptgründe für seine Verwendung. –

+0

Vielleicht warum ich keine Antwort gefunden habe ... was ist eine Alternative? @Rodit Ich versuche, alles andere zu stoppen, bis die 5 Sekunden Dauer auf der Tür-Timer, und autoclose, die Hauptfunktion Ausführung, die für das Passwort –

Antwort

1

Wie durch die Dokumentation erwähnt, Timer sind:

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

Dies bedeutet, ein Teil des Programmlaufs ein Timertask verwendet, wird vom Haupt auf einem separaten Thread ausgeführt werden, und wird daher nicht Ausführung auf dem Hauptthread blockieren.

Eine alternative Lösung wäre es, den Faden für die gewünschte Anzahl von Sekunden zu schlafen, wie folgt (die Timer() Methode mit dieser ersetzen und die InterruptedException fangen.):

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. 
    } 
} 

Und Ihre Autoclose Verfahren ersetzen mit diesem:

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 wirft ein InterruptedException so muss diese angemessen gehandhabt werden.

+0

Sieht so aus, als würde man nach remote.toggleDoor, die den Timer einleitet, in den main-Modus schalten, der Ausgang "Door is closed" wird trotzdem nicht verhindert. –

+0

Entschuldigung, ich glaube, Sie haben falsch verstanden, wo Sie das hinstellen sollten. Ich werde es in einer zweiten @DannyP klarer machen. – rodit

+0

Okay, ich verstehe, es wird den Timer, den ich geschrieben habe, ersetzen –