2013-08-27 11 views
5

Ho una situazione in cui più thread eseguiranno il polling di un singolo BlockingQueue chiamando take(). Quello che voglio sapere è il seguente:BlockingQueues e ordine di accesso al thread

Se più thread attendono che la coda riceva un articolo, verrà data priorità alla rimozione degli articoli dalla coda nell'ordine in cui hanno effettuato le loro chiamate() o l'ordine in cui i thread rimuovono le cose dalla coda sarà arbitrario?

Grazie!

Nota: ho già scritto le mie implementazioni per questo genere di cose in passato, ma mi chiedo se le implementazioni di BlockingQueue in Java possano farlo per me.

+1

In generale, qualsiasi applicazione con multithreading non dovrebbe formulare alcuna ipotesi sull'ordine di esecuzione del thread. Ci sono modi per applicarlo, ma l'idea dietro le applicazioni MT è che non dovrebbe essere fatto. – Dariusz

+1

Interessante domanda, ho scritto ed eseguito un programma - non esiste un ordine fisso. – Tala

+1

[domanda correlata] (http://stackoverflow.com/questions/1301691/java-queue-implementations-which-one) che parla anche di equità. –

risposta

4

Dipende dall'implementazione.

Se si utilizza un LinkedBlockingQueue, i controlli take() metodo con un ReentrantLock

public E take() throws InterruptedException { 
    E x; 
    int c = -1; 
    final AtomicInteger count = this.count; 
    final ReentrantLock takeLock = this.takeLock; 
    takeLock.lockInterruptibly(); 
    ... 
} 

// declared as 
private final ReentrantLock takeLock = new ReentrantLock(); // no fairness argument, defaults to false 

Il javadoc dice

Il costruttore per questa classe accetta un parametro di equità opzionale. Se impostato true, sotto contention, i blocchi preferiscono la concessione dell'accesso al thread con attesa più lunga . Altrimenti questo blocco non garantisce alcun ordine di accesso particolare. I programmi che utilizzano blocchi equi accessibili da molti thread possono visualizzare un throughput complessivo inferiore (ad esempio, più lento, spesso molto più lento) rispetto a quelli che utilizzano l'impostazione predefinita, ma hanno minori variazioni di volte per ottenere blocchi e garantire la mancanza di fame. Si noti tuttavia che la correttezza delle serrature non garantisce l'equità della schedulazione dei thread . Pertanto, uno dei molti thread che utilizza un blocco corretto può ottenere più volte in successione mentre altri thread attivi sono non in progresso e non attualmente in possesso del blocco. Si noti inoltre che il metodo tryLock senza orario non rispetta l'impostazione di equità. Sarà riuscito se il blocco è disponibile anche se altri thread sono in attesa.

2

In molti casi i javadoc menzionano se la classe è "equa", cioè il blocco è distribuito in modo che tutti i thread abbiano la stessa possibilità. Ciò non significa necessariamente lo stesso di "ottiene nello stesso ordine" comunque. Controlla i javadoc per la tua particolare implementazione della coda per vedere se ha informazioni su equità e/o ordine.

Almeno ArrayBlockingQueue informa di equità come segue:

Questa classe supporta una politica di equità facoltativa per l'ordinazione in attesa produttori e consumatori discussioni. Per impostazione predefinita, questo ordine non è garantito . Tuttavia, una coda costruita con equità impostata su true concede l'accesso ai thread nell'ordine FIFO. L'equità generalmente diminuisce il throughput ma riduce la variabilità ed evita la fame.

1

Dipende dall'implementazione, indipendentemente dal fatto che una classe supporti una politica di equità opzionale per ordinare i thread di attesa del produttore e del consumatore oppure no. Per esempio.ArrayBlockingQueue può essere equo poiché ha il costruttore ArrayBlockingQueue (int capacity, boolean fair), ma LinkedBlockingQueue non può.

Problemi correlati