2012-03-08 12 views
8

Recentemente stavo scrivendo un programma concorrente in Java e ho trovato il dilemma che stava per svanire: supponiamo di avere una struttura dati globale, che è parte di una normale libreria non sincronizzata, non simultanea come HashMap. Va bene consentire a più thread di scorrere l'insieme (solo leggendo, senza modifiche), magari in periodi diversi, intercalati, cioè thread1 potrebbe essere a metà strada per iterare quando thread2 ottiene il suo iteratore sulla stessa mappa?Più thread che iterano sulla stessa mappa

+0

Come dici tu, i thread hanno iteratori diversi. Dal momento che non sono condivisi, non ci sono problemi. –

+0

Grazie ragazzi, ottime risposte! – Bober02

risposta

12

È OK. La capacità di farlo è la ragione per creare tale interfaccia come iteratore. Ogni thread che itera su una raccolta ha una sua istanza di iteratore che mantiene il suo stato (ad esempio, dove ci si trova ora nel processo di iterazione).

Ciò consente a più thread di scorrere simultaneamente sulla stessa raccolta.

4

I problemi sorgono solo quando si tentano modifiche simultanee su una struttura di dati.

Ad esempio, se un thread sta iterando sul contenuto di una mappa e un altro thread cancella gli elementi da quella raccolta, si andrà verso un problema serio.

Se sono necessari alcuni thread per modificare tale raccolta in modo sicuro, Java fornisce meccanismi per farlo, ovvero ConcurrentHashMap.

ConcurrentHashMap in Java?

C'è anche Hashtable, che ha la stessa interfaccia HashMap, ma è sincronizzato, anche se il suo uso non è consigliato attualmente (sconsigliato), in quanto la sua prestazione soffre quando il numero di elementi diventa più grande (rispetto a ConcurrentHashMap che non ha bisogno di bloccare l'intera Collezione).

Se si dispone di una raccolta che non è sincronizzata e è necessario disporre di più thread di lettura e scrittura su di essa, è possibile utilizzare Collections.synchronizedMap (Map) per ottenere una versione sincronizzata di esso.

7

Dovrebbe andare bene, finché non ci sono scrittori.

Questo problema è simile a readers-writer lock, in cui più lettori sono autorizzati a leggere dai dati, ma non durante il periodo in cui uno scrittore "ha" il blocco per esso. Non vi è alcun problema di concorrenza per i multipli letti contemporaneamente. [data race si può verificare solo quando si ha almeno una scrittura].

2

Le risposte di cui sopra sono certamente un buon consiglio. In generale, quando si scrive Java con thread simultanei, purché non si modifichi una struttura dati, non è necessario preoccuparsi di più thread che leggono contemporaneamente quella struttura.

In caso di problemi simili in futuro, tranne che la struttura dati globale potrebbe essere modificata contemporaneamente, suggerirei di scrivere una classe Java che tutti i thread utilizzano per accedere e modificare la struttura. Questa classe potrebbe implementare la propria metodologia di concorrenza, utilizzando metodi sincronizzati o blocchi. Il tutorial Java ha un'ottima spiegazione dei meccanismi di concorrenza di Java. L'ho fatto personalmente ed è abbastanza semplice.

Problemi correlati