2011-12-29 16 views
17

In Java Concurrency in Practice libro (p.156), c'è una dichiarazione per quanto riguarda veleno pillola approccio:È possibile utilizzare l'approccio con pillola avvelenata con code limitate?

veleno pillole funzionano in modo affidabile solo con le code non legati.

Significa che con una coda limitata posso ottenere un deadlock o si tratta di altri problemi di vividezza? È collegato al numero di produttori e clienti?

+0

Non riesco a capire il problema con le code limitate – gstackoverflow

+0

È collegato alla correttezza? – gstackoverflow

risposta

7

Con una coda limitata, è possibile impedire l'aggiunta della pillola del veleno.

Un modo per evitare questo problema consiste nel consentire che la coda limitata ne consenta un'altra quando viene aggiunta una pillola avvelenata.

+0

Bene, ogni thread in attesa di poter aggiungere qualche elemento in coda potrebbe essere sbloccato e la pillola avvelenata sarebbe ancora fuori dalla coda. Esiste un'implementazione di coda standard con una capacità variabile? –

+0

Sì, certo, ma questo vale solo per le code non bloccanti. –

+0

@JBNizet Non ne conosco nessuno, dovrebbe essere supportato nell'implementazione per evitare condizioni di gara. –

6

Il problema è che la coda potrebbe essere piena a breve distanza.

Dipende dal valore dei dati in coda al momento della chiusura. Puoi permetterti di buttare via tutto in fila?

Quando arriva il momento di chiudere la coda, dovrebbe essere efficace per scaricare la coda prima di aggiungere la pillola del veleno.

void close() throws InterruptedException { 
    do { 
    // Empty the queue. 
    while (queue.poll(0,TimeUnit.MILLISECONDS) != null) { 
     // Throw it away. 
    } 
    // Keep draining the queue 'till the pill is swallowed. 
    } while (!queue.offer(STOP, 0, TimeUnit.MILLISECONDS)) ; 
} 

ma ovviamente se gli elementi nella coda sono utili si potrebbe desiderare di utilizzare drainto e preservarli.

prega di tenere anche presente che ci possono essere più elementi aggiunti alla coda dopo che la pillola di veleno, perché non solo potrebbe essere la coda piena, ma ci possono essere anche le discussioni bloccati in attesa di inviare ad esso.

+0

per favore spieghi il problema dell'uso delle code limitate – gstackoverflow

1

@gstackoverflow: il problema principale della coda limitata è che ha una capacità massima, quindi se la coda delimitata è piena, verrà bloccato quando si desidera aggiungere questa "pillola avvelenata".

Tenete a mente che la pillola di veleno deve essere posto immediatamente e non può aspettare fino a quando la coda ha un pò di spazio, come questa tecnica è utilizzata per spegnere con garbo i consumatori quando si verifica un'eccezione (altrimenti non esiste tecnica più bello per i consumatori di arresto).

Edit: Per fare un esempio parla più di mille frasi vediamo un semplice esempio (tutti i crediti per l'esempio vanno a Java Concurrency in Practice), con un filo produttore e un filetto dei consumatori:

public class CrawlerThread extends Thread { //The Producer Thread 
    public void run() { 
    try { 
     crawl(root); 
    } catch (InterruptedException e) { /* fall through */ } 
    finally { 
     while (true) { 
     try { 
      queue.put(POISON); 
      break; 
     } catch (InterruptedException e1) { /* retry */ } 
     } 
    } 
    } 
    private void crawl(File root) throws InterruptedException { 
    //some code 
    } 
} 
public class IndexerThread extends Thread { //The consumer Thread 
    public void run() { 
    try { 
     while (true) { 
     File file = queue.take(); 
     if (file == POISON) 
     break; 
     else 
     indexFile(file); 
     } 
    } catch (InterruptedException consumed) { } 
    } 
} 

Ora, quando si esamina il thread di produzione (CrawlerThread), si vede che la pillola velenosa viene posta alla fine della corsa o in una situazione più terribile, quando si verifica un'eccezione.

Ora diciamo che vuoi usare una coda limitata come interfaccia tra il produttore e il consumatore, supponiamo che la coda sia piena all'istante t, e un'eccezione si verifica nel produttore al tempo t, il produttore non lo farà essere in grado di mettere la pillola velenosa in coda e invece di chiudere il thread dei consumatori, il consumatore attenderà ancora che gli elementi entrino in coda. Ecco perché l'approccio Poison pill non è raccomandato se si utilizza una coda limitata, poiché potrebbe potenzialmente portare a un risultato imprevisto.

+0

Dove hai trovato il testo in grassetto? Perché il thread non può essere sempre bloccato? – gstackoverflow

+0

Vedere la mia modifica, fammi sapere se fa luce sulla tua domanda – Adonis

+0

di InterruptedException? Ciò può verificarsi in caso di coda illimitata, tuttavia * aggiungere * alla coda richiede un po 'di tempo e può verificarsi anche contesa, non vedo ancora la differenza – gstackoverflow

0

penso che l'autore (s) di Java concorrenza in pratica può tentare di dire questo:

Quando si aggiunge un nuovo messaggio a un completo coda limitata, sia il nuovo messaggio o uno dei messaggi esistenti viene lasciato cadere. Quindi è possibile che l'applicazione continui a rilasciare pillole avvelenate per sempre prima che possano diventare il prossimo messaggio disponibile.

La logica può essere aggiunta, tuttavia. Ad esempio, potremmo far valere le pillole avvelenate che vengono sempre aggiunte e mai rimosse. Nel qual caso una coda limitata potrebbe effettivamente funzionare.

Problemi correlati