2010-09-26 2 views
12

Ich habe ein Szenario, in dem ich einen Thread für bestimmte Zeit schlafen will.Wie man einen Thread für eine bestimmte Zeit in Java schlafen lässt?

Code:

public void run(){ 
     try{ 
      //do something 
        Thread.sleep(3000); 
//do something after waking up 
       }catch(InterruptedException e){ 
       // interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds? 
       } 
     } 

Nun, wie gehe ich mit dem Fall, in dem der Faden i vor dem vollständigen des Schlaf mit einer unterbrochenen Ausnahme getroffen zu laufen bin versucht wird? Auch hat der Faden wake up unterbrochen und geht es um runnable Zustand oder wenn ist es, dass erst, nachdem es RUNNABLE geht wird der Strom schwimmen Block zu fangen?

Antwort

1
  1. mit Schlaf in meiner Erfahrung ist in der Regel zu kompensieren schlechtes Timing woanders im Programm, überdenken!
  2. versuchen Sie dies:

    public void run(){ 
         try{ 
          //do something 
          long before = System.currentTimeMillis(); 
          Thread.sleep(3000); 
          //do something after waking up 
         }catch(InterruptedException e){ 
          long diff = System.currentTimeMillis()-before; 
          //this is approximation! exception handlers take time too.... 
          if(diff < 3000) 
           //do something else, maybe go back to sleep. 
           // interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds? 
         } 
    } 
    
  3. , wenn Sie den Schlaf nicht selbst unterbrechen, warum sollte dieser Thread aufgeweckt werden? ist, scheint, dass Sie etwas sehr falsch ...

+0

Der Interrupt kann von einem externen Ereignis stammen, z. B. vom Betriebssystem als "ordnungsgemäßes Herunterfahren". –

+0

@Tony: Es ist das gleiche Prinzip. die Unterbrechung gibt immer noch einen bewussten Wunsch, den Faden zu stornieren, es ist nicht irgendeine Art von planlos Fall, dass der Thread „Hit“ wird mit, wie die Formulierung der OP zu implizieren scheint. –

1

Nach this page tun Sie es codieren müssen werden, wie Sie wollen verhalten. Wenn du den Thread oberhalb deines Schlafs verwendest, wird er unterbrochen und dein Thread wird beendet. Im Idealfall würden Sie die Ausnahme erneut auslösen, sodass der Benutzer, der den Thread gestartet hat, entsprechende Maßnahmen ergreifen könnte.

Wenn Sie nicht das geschehen soll, könnte man das Ganze in einer while (true) Schleife setzen. Jetzt, wenn der Interrupt passiert, wird der Schlaf unterbrochen, Sie essen die Ausnahme und schließen sich an, um einen neuen Schlaf zu beginnen.

Wenn Sie die 3 Sekunden Schlaf abschließen möchten, können Sie es nähern, indem er, sagen wir, 10 Betten von 300 Millisekunden, und außerhalb einer while-Schleife der Schleifenzähler zu halten. Wenn du die Unterbrechung siehst, iss sie, setze eine "Ich muss sterben" -Flagge und mache weiter, bis du genug geschlafen hast. Dann unterbrichst du den Thread kontrolliert.

Hier ist eine Art und Weise:

public class ThreadThing implements Runnable { 
    public void run() { 
     boolean sawException = false; 
     for (int i = 0; i < 10; i++) { 
      try { 
       //do something 
       Thread.sleep(300); 
       //do something after waking up 
      } catch (InterruptedException e) { 
       // We lose some up to 300 ms of sleep each time this 
       // happens... This can be tuned by making more iterations 
       // of lesser duration. Or adding 150 ms back to a 'sleep 
       // pool' etc. There are many ways to approximate 3 seconds. 
       sawException = true; 
      } 
     } 
     if (sawException) Thread.currentThread().interrupt(); 
    } 
} 
1

Warum Sie genau 3 Sekunden schlafen wollen? Wenn Sie nach einiger Zeit etwas ausführen müssen, versuchen Sie es mit einem Timer.

+0

Timer wäre besser, aber es bietet das Potenzial für Race & Concurrency Probleme, die durch schlafen vermieden werden könnte. Ich denke jedoch, es wäre die Lernkurve wert, Timer zu verwenden. – locka

+0

der oben genannte Timer-Link scheint gebrochen zu sein – AkD

10

Wenn Ihr Faden durch eine Unterbrechung getroffen wird, wird es in den InterruptedException catch-Block gehen. Sie können dann überprüfen, wie viel Zeit der Thread verbracht hat zu schlafen und herauszufinden, wie viel mehr Zeit zu schlafen ist. Schließlich, anstatt die Ausnahme zu verschlucken, ist es eine gute Übung, den Unterbrechungsstatus wiederherzustellen, so dass der Code, der sich oben auf dem Aufrufstapel befindet, damit umgehen kann.

public void run(){ 

    //do something 

    //sleep for 3000ms (approx)  
    long timeToSleep = 3000; 
    long start, end, slept; 
    boolean interrupted; 

    while(timeToSleep > 0){ 
     start=System.currentTimeMillis(); 
     try{ 
      Thread.sleep(timeToSleep); 
      break; 
     } 
     catch(InterruptedException e){ 

      //work out how much more time to sleep for 
      end=System.currentTimeMillis(); 
      slept=end-start; 
      timeToSleep-=slept; 
      interrupted=true 
     } 
    } 

    if(interrupted){ 
     //restore interruption before exit 
     Thread.currentThread().interrupt(); 
    } 
} 
1

Ich benutze es auf diese Weise:

So ist es nicht notwendig, die spezifische Zeit zu warten bis zum Ende.

public void run(){ 

    try { 

     //do something 

     try{Thread.sleep(3000);}catch(Exception e){} 

     //do something 

    }catch(Exception e){} 

}