come verificare ConcurrentHashMap è thread-safe?

5

Come diceva il documento jdk, ConcurrentHashMap è thread-safe e non blocca più thread read. Non è necessario dubitarne poiché è stato sottoposto a molti test ristretti. Ma sono solo curioso di sapere come scrivere e scrivere il codice per verificarlo.

Modificato : per essere più preciso

  1. come mantenere il consenso di lettura senza blocco di lettura
  2. restituisce l'ultima visualizzazione dei dati
posta pythonee 18.11.2012 - 05:03
fonte

3 risposte

5

A tutti gli scopi pratici, non puoi. È possibile eseguire numerose prove con successo numerose volte, quindi senza apportare modifiche, un test fallirà. Questo è ciò che rende difficile testare il multi-threading - non è deterministico.

Potresti essere in grado di testare con un grado accettabile di certezza usando metodi statistici, cioè abbiamo eseguito 10 ^ test randomizzati senza errori trovati- è statisticamente probabile che non ci siano difetti.

Non è possibile eseguire un test che garantisca la sicurezza del thread, ma deve essere eseguito in base alla progettazione e al test della white box che il progetto sia stato implementato correttamente.

Per quanto riguarda ConcurrentHashMap - se il tuo venditore dice che qualcosa è sicuro per i thread, puoi solo decidere, mi fido del mio venditore - o forse parafrasando una grande linea di film "Devi pormi una domanda: mi sento fortunato "Beh, vero, punk?" - e se non ti fidi del tuo venditore, penso che tu abbia problemi più grandi.

EDIT: Il mio background coinvolge sistemi embedded Life critical e Hard Real time (sub nanosecondi). Le mie domande hanno una risposta nel contesto di "Qual è la cosa peggiore che succede" essendo un po 'più importante di "un crash del software inspiegabile" ......

    
risposta data 18.11.2012 - 06:08
fonte
3

Prima di tutto, non hai mai realmente bisogno di aggirare i framework di testing unitario, specialmente non il framework principale di una lingua.

La verifica dei test di unità per la sicurezza dei thread può essere un po 'complicata, specialmente se non si è super chiari sulla gestione del threading / concorrenza. Inoltre, generalmente non ottieni garanzie impeccabili al 100% (anche se per alcuni scenari puoi farlo), ma puoi farlo dannatamente bene usando tecniche appropriate.

Detto questo, è una questione di definire i comportamenti che non vuoi e tentare di causarli, quindi avere test che assicurano il comportamento desiderato era invece in gioco.

Per questo particolare scenario con i passaggi che ho esposto devi:

  • Definisci i comportamenti che non vuoi: non vuoi che le letture vengano bloccate.
  • Tentativo di causarli: crea due thread che provano a leggere dal dizionario alla stessa ora (usa un evento basato sul segnale o sul timestamp per entrambi).
  • Prova invece il comportamento desiderato: timestamp prima e dopo l'operazione di lettura, assicurati che i timestamp siano iniziati e terminati con sovrapposizioni tra i due thread.

Questo è un approccio subparente, anche perché stai testando la sicurezza dei thread in qualcosa in cui non hai accesso alle viscere del sistema, quando scrivi i tuoi sistemi di threading il trucco è forzare le operazioni a impiegare più tempo nel casi test. Normalmente metto gli oggetti mock nel mezzo del blocco o delle operazioni non bloccanti e forzano il sonno, quindi assicurati che i timestamp non si sovrappongano o meno come previsto, a seconda se voglio vedere il blocco o non voglio vedere il blocco.

    
risposta data 18.11.2012 - 06:19
fonte
3

But I just curious how to tell and write code to verify that.

Dipende da cosa intendi con "verifica". Il normale significato di "verifica" di Computer Science è quello di mostrare che qualcosa è vero / corretto ... tutto il tempo, non solo alcuni o il più delle volte.

In alcuni casi, è possibile mostrare che la cosa è vera (ad esempio determinati invarianti sono sempre soddisfatti) semplicemente testando. Ma l'unico modo per farlo testando è testare tutti i possibili input / condizioni di partenza; cioè mediante esaustivo test Nei casi che implicano un comportamento multi-thread, di solito non è possibile farlo.

Questo non vuol dire che il test sia inutile per applicazioni multi-thread. Ma come qualcuno ha detto (Tony Hoare?) I test possono dimostrare la presenza di bug, ma non l'assenza di bug. Il solo test non è sufficiente per verificare la correttezza del codice multi-thread.

L'unico modo per verificare (nel senso accettato) che ConcurrentHashMap sia thread-safe consiste nell'analizzare il codice sorgente e costruire una dimostrazione di correttezza formale o informale per i criteri di sicurezza del thread. Questo è un duro lavoro. E in più, la "sicurezza del filo" è in realtà un concetto piuttosto difficile da legare in senso formale. (Fondamentalmente, significa "funziona correttamente quando ci sono più thread" ... che pone la domanda - che cosa significa "funziona correttamente"?

    
risposta data 18.11.2012 - 08:18
fonte

Leggi altre domande sui tag