2013-07-24 11 views
16

Entschuldigung für diese wiederholte Frage, aber ich habe noch keine befriedigenden Antworten gefunden. Die meisten der Frage hatten ihren eigenen spezifischen Anwendungsfall:
Java - alternative to thread.sleep
Is there any better or alternative way to skip/avoid using Thread.sleep(1000) in Java?Warum Thread.sleep ist schlecht zu verwenden

Meine Frage ist für den sehr allgemeinen Anwendungsfall. Warten Sie, bis eine Bedingung erfüllt ist. Tun Sie etwas Operation. Auf einen Zustand prüfen. Wenn die Bedingung nicht erfüllt ist, warten Sie einige Zeit und wiederholen Sie den Vorgang.

Für z.B. Stellen Sie sich eine Methode vor, die eine DynamoDB-Tabelle durch Aufrufen ihrer createAPI-Tabelle erstellt. Die DynamoDB-Tabelle braucht etwas Zeit, um aktiv zu werden, so dass die Methode ihre DescribeTable-API aufrufen würde, um in regelmäßigen Abständen bis zu einem gewissen Zeitpunkt nach dem Status zu suchen (sagen wir 5 Minuten - Abweichung aufgrund der Thread-Planung ist akzeptabel). Gibt "true" zurück, wenn die Tabelle in 5 Minuten aktiv wird, andernfalls "Ausnahme".

Hier ist Pseudo-Code:

public void createDynamoDBTable(String name) { 
    //call create table API to initiate table creation 

    //wait for table to become active 
    long endTime = System.currentTimeMillis() + MAX_WAIT_TIME_FOR_TABLE_CREATE; 

    while(System.currentTimeMillis() < endTime) { 
    boolean status = //call DescribeTable API to get status; 
    if(status) { 
     //status is now true, return 
     return 
    } else { 
     try { 
      Thread.sleep(10*1000); 
     } catch(InterruptedException e) { 
     } 
    } 
    } 

    throw new RuntimeException("Table still not created"); 
} 

Ich verstehe, dass durch die Verwendung Thread.sleep Blockiert den aktuellen Thread, wodurch Ressourcen verbraucht. aber in einer ziemlich mittleren Anwendung ist ein Thread ein großes Problem?
Ich habe irgendwo gelesen, ScheduledThreadPoolExecutor verwenden und diesen Status dort abfragen. Aber noch einmal, wir müssten diesen Pool mit mindestens 1 Thread initialisieren, wo die ausführbare Methode ausgeführt werden würde.

Irgendwelche Vorschläge, warum mit Thread.sleep zu verwenden ist eine so schlechte Idee und was sind die alternativen Möglichkeiten, um das gleiche wie oben zu erreichen.

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

+2

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx – stinepike

+4

Ihr Link ist über .Net. Es gilt nicht für Java. –

+0

Polling ist schlecht, kein Zweifel. Aber wenn Sie keine Alternativen haben, ist es das Mindeste, was Sie beachten sollten. –

Antwort

24

Es ist in Ordnung Thread.sleep in dieser Situation zu verwenden. Der Grund, warum Leute davon abraten, Thread.sleep zu entmutigen, ist, dass sie häufig bei einem schlechten Versuch verwendet wird, eine Wettlaufbedingung zu beheben.

In diesem Fall haben Sie keine Option, sondern Poll weil die API keine Benachrichtigungen bereitstellt. Ich kann auch sehen, dass es eine seltene Operation ist, weil Sie vermutlich keine tausend Tabellen erstellen werden.

Daher finde ich es gut, Thread.sleep hier zu verwenden. Wie du schon sagtest, einen anderen Thread zu generieren, wenn du den aktuellen Thread sowieso blockierst, scheint Dinge ohne Erfolg zu verkomplizieren.

+9

Ein großer Vorbehalt: Stellen Sie sicher, dass der schlafende Thread nicht an knappen Ressourcen hält, wie eine Mutex- oder Datenbankverbindung. – yshavit

+0

Wäre dieses Muster auch im folgenden Fall akzeptabel? - Abrufen von SQS für jeweils eine Nachricht und Verwalten einer Liste von Nachrichten. Wenn die Größe der Liste die X-Nummer erreicht, verarbeiten Sie sie in großen Mengen. Wenn in SQS keine weiteren Nachrichten vorhanden sind, ruhen Sie einige Zeit. Wiederum Umfrage danach. – RandomQuestion

+0

@Jitendra: Normalerweise mit MQs möchten Sie vermeiden, Polling, aber AFAIK gibt es keinen anderen Weg als Poll in SQS (die übrigens berechnen, auch wenn es keine Nachricht), so 'Thread.Sleep' ist ein Möglichkeit. Ich könnte jedoch geneigt sein, geplante Executor zu verwenden, weil es das Hinzufügen von Consumern erleichtert, die Planung von Abfragen verfeinert und Sie zwingt, Geschäftslogik und Infrastruktur voneinander zu trennen. –

2

Ja, sollte man versuchen, Nutzung von Thread.sleep zu vermeiden (x), aber es sollte nicht ganz vergessen werden:

Warum es

  • Es ist nicht die Sperre sollte vermieden werden
  • es gurantee nicht, dass die Ausführung nach dem schlafen Zeit beginnen (So kann es für immer warten lassen - offensichtlich einen seltenen Fall)
  • Wenn wir Thread eine Vordergrundverarbeitung auf den Schlaf setzen fälschlicherweise dann Wo wir Diese Anwendung kann nicht bis x Millisekunden geschlossen werden.
  • Wir sind jetzt voll mit neuen Concurrency-Paket für bestimmte Probleme geladen (wie Design-Muster (natürlich nicht genau), warum Thread.sleep (x) dann verwenden.

    • Zur Bereitstellung Verzögerungen im Hintergrund laufenden Threads
    • Und einige andere:

    Wo Thread.sleep (x) verwenden.

+0

Verwenden Sie keine Angebotsformatierung für Text, der nicht zitiert wird. – EJP

Verwandte Themen