2014-04-30 13 views
18

Quando si consumano i valori da una coda in un ciclo infinito - quello che sarebbe più efficiente:Java BlockingQueue take() vs poll()

1) Blocco sulla coda fino a quando un valore è disponibile tramite take()

while (value = queue.take()) { doSomething(value); } 

2) Dormire per n millisecondi e controllando se un articolo è disponibile

while (true) { 

    if ((value = queue.poll()) != null) { doSomething(value); } 

    Thread.sleep(1000); 
} 
+1

secondo la mia esperienza, il thread è il modo migliore per produrre/consumare messaggi in blockingqueue. –

+0

come può java avere un ciclo while con un'istruzione di assegnazione come condizione? – davidchoo12

+0

"Efficiente" può essere un sacco di cose: bassa latenza, throughput più elevato, meno consumo di energia (mobile), ecc. Otterrete risposte più adatte se fornite più informazioni di base. – Renan

risposta

41

blocco è probabilmente più efficiente. In background, il thread che inizialmente chiama take() entra in stato di sospensione se non è disponibile alcun elemento, consentendo agli altri thread di fare tutto ciò che devono fare. I metodi che aggiungono elementi alla coda risveglieranno quindi i thread in attesa quando viene aggiunto un elemento, quindi viene dedicato un tempo minimo a controllare la coda più e più volte per verificare se un elemento è disponibile.

+1

+1 per una risposta semplice ben spiegata. – JamesENL

+10

È meglio utilizzare una soluzione con timeout per non bloccare un thread per un momento indeterminato. Pertanto, una buona implementazione consiste nell'utilizzare il 'poll (timeout, unit)' specialmente se il thread è eseguito da un ThreadPool e attende l'esecuzione di un'altra attività. – Pierrick

0

Fare attenzione quando si utilizza take(). Se si utilizza take() da un servizio e il servizio ha una connessione db.

Se take() viene restituito dopo il periodo di timeout di connessione non aggiornato, verrà generata un'eccezione di connessione Stallo.

Utilizzare il polling per il tempo di attesa predefinito e aggiungere il controllo null per l'oggetto restituito.