2013-06-04 18 views
18

Durante la lettura di concorrenza in Java, ho seguenti dubbi:sincronizzato Vs Semaforo

  1. fa Java fornisce inferiore costrutto livello allora sincronizzato per la sincronizzazione?

  2. In quali circostanze saranno utilizzate semaforo sopra sincronizzato (che fornisce il comportamento monitor Java)

+0

penso che per la domanda 1, possiamo usare gli oggetti ReentrantLock e Condition, sono una specie di costrutto di livello inferiore. – Addict

risposta

34

sincronizzato consente solo uno thread di esecuzione per accedere alla risorsa allo stesso tempo. Il semaforo consente fino a n (è possibile scegliere n) i thread di esecuzione per accedere alla risorsa contemporaneamente.

8
  1. C'è anche volatile parola, secondo http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.htmlvolatile accesso variabile è più efficiente di accesso a tali variabili tramite codice sincronizzato

  2. java.util.concurrent.Semaphore viene utilizzato per limitare il numero di fili che può accedere a una risorsa. Cioè, mentre synchronized consente a un solo thread di acquisire il lock ed eseguire il blocco/metodo synchonized, Semaphore dà il permesso fino a n thread per andare e blocca gli altri.

+0

sincronizzato fornisce una soluzione a entrambi gli errori di coerenza di thread e di consistenza della memoria, tuttavia la soluzione volatile fornisce solo soluzioni agli errori di coerenza della memoria, quindi non possiamo usare volatile per fornire l'atomicità nelle operazioni, mi manca qualcosa qui? – Addict

+0

volatile fornisce anche l'accesso atomico a long/double –

+0

Con volatile si possono ancora avere letture sporche e corrompere i valori condivisi. Quindi non è un'alternativa per sincronizzati. –

2

C'è anche atomics. Ciò consente di accedere al comando di base di confronto e scambio dell'hardware che è alla base di tutte le sincronizzazioni. Permette, ad esempio, di incrementare un numero in modo sicuro. Se il campo ++ è volatile, un altro thread che esegue la stessa istruzione potrebbe leggere il campo prima che il thread lo scriva, quindi riscriverlo a dopo il thread. Quindi un incremento si perde. Gli atomici leggono e scrivono "atomicamente" e quindi evitano il problema.

In realtà, volatili, dichiarazioni sincronizzato, e Atomics tendono a forzare tutti i dati thread per essere aggiornati dalla memoria principale e/o scritti in memoria principale a seconda dei casi, in modo da nessuno di loro sono veramente che il basso livello. (Sto semplificando qui. A differenza di C#, Java non ha un concetto di "memoria principale".)