2013-07-24 14 views
16

Ci scusiamo per questa domanda ripetuta, ma non ho ancora trovato risposte soddisfacenti. La maggior parte della domanda hanno avuto loro caso specifico impiego:
Java - alternative to thread.sleep
Is there any better or alternative way to skip/avoid using Thread.sleep(1000) in Java?Perché Thread.sleep è male da usare

La mia domanda è per il caso d'uso molto generico. Attendere il completamento di una condizione. Fai qualche operazione. Verifica una condizione. Se la condizione non è vera, attendere qualche volta e fare nuovamente la stessa operazione.

Ad es. Considera un metodo che crea una tabella DynamoDB chiamando la sua tabella createAPI. La tabella DynamoDB impiega del tempo per diventare attiva in modo che il metodo chiami la sua API DescribeTable per eseguire il polling dello stato a intervalli regolari fino a qualche tempo (diciamo 5 minuti - la deviazione dovuta alla pianificazione dei thread è accettabile). Restituisce true se la tabella diventa attiva in 5 minuti altrimenti genera un'eccezione.

Ecco pseudo-codice:

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"); 
} 

ho capito che utilizzando Thread.sleep blocca il thread corrente, consumando in tal modo le risorse. ma in un'applicazione di dimensioni abbastanza medie, un thread è un grosso problema?
Ho letto da qualche parte che usa ScheduledThreadPoolExecutor e faccio questo polling di stato lì. Ma ancora una volta, dovremmo inizializzare questo pool con almeno 1 thread in cui il metodo eseguibile per eseguire il polling sarebbe eseguito.

Qualsiasi suggerimento sul motivo per cui l'uso di Thread.sleep è considerato una cattiva idea e quali sono le opzioni alternative per ottenere lo stesso come sopra.

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

Il tuo collegamento è circa .Net. Non si applica a Java. –

+0

Il polling è sbagliato, senza dubbio. Ma se non hai alternative, è la cosa meno importante che ti interessi. –

risposta

24

E 'bene usare Thread.sleep in quella situazione. La ragione per cui le persone scoraggiano Thread.sleep è perché viene spesso utilizzata in un tentativo illecito di correggere una condizione di competizione, usata quando la sincronizzazione basata sulla notifica è una scelta molto migliore ecc.

In questo caso, AFAIK non hai un'opzione ma sondare perché l'API non ti fornisce notifiche. Posso anche vedere che è un'operazione rara perché presumibilmente non creerai più tabelle.

Quindi, trovo bene usare Thread.sleep qui. Come hai detto, generare un thread separato quando stai per bloccare il thread corrente sembra comunque complicare le cose senza merito.

+9

Un grande avvertimento: assicurati che il thread non stia trattenendo risorse scarse, come una connessione mutex o database. – yshavit

+0

Questo modello sarebbe accettabile anche nel seguente caso? - Sondare SQS per un messaggio alla volta e mantenere un elenco di messaggi. Quando la dimensione dell'elenco raggiunge il numero X, elaborali alla rinfusa. Se non ci sono più messaggi in SQS, dormi per qualche tempo. Di nuovo sondaggio dopo. – RandomQuestion

+0

@Jitendra: Solitamente con MQ si vorrebbe evitare il polling, ma AFAIK non ha altro modo che eseguire il polling in SQS (che, a proposito, si carica anche quando non c'è alcun messaggio), quindi 'Thread.sleep' è un opzione. Potrei essere incline ad usare l'esecutore programmato anche se rende facile aggiungere utenti, ottimizzare la programmazione dei sondaggi e costringe a separare la logica e l'infrastruttura di business. –

2

Sì, si dovrebbe cercare di evitare l'uso di Thread.sleep (x), ma non dovrebbe essere completamente dimenticato:

Perché dovrebbe essere evitato

  • non rilascia il blocco
  • non gurantee che l'esecuzione avrà inizio dopo il tempo di sonno (Così può continuare ad aspettare per sempre - ovviamente un caso raro)
  • Se noi erroneamente messo un thread di elaborazione in primo piano sul sonno poi abbiamo wo Non potrei chiudere quell'applicazione fino a x millisecondi.
  • Ora abbiamo pieno di nuovi pacchetti di concorrenza per problemi specifici (come i modelli di progettazione (ofcourse non esattamente), perché utilizzare Thread.sleep (x) quindi.

Dove usare Thread.sleep (x):

  • Per fornire ritardi in background in esecuzione discussioni
  • E pochi altri.
+0

Non utilizzare la formattazione delle quote per il testo non quotato. – EJP