2010-11-01 15 views
15

Dire che ho una matrice di migliaia di oggetti e un piccolo numero di thread che potrebbero accedere a ciascuno degli oggetti. Voglio proteggere l'accesso a uno dei metodi degli oggetti. Il modo più semplice sarebbe dichiarare tale metodo come synchronized. Tuttavia, ciò potrebbe comportare la creazione di migliaia di monitor, indipendentemente dal modo in cui vengono implementati. Se questo fosse Win32, non creerei mai migliaia di oggetti del kernel come Mutex, ma CRITICAL_SECTIONs potrebbe essere plausibile. Mi chiedo cosa succede in Java. Data la possibilità di contesa è bassa, l'uso di monitor imporrebbe più della quantità di memoria che richiedono? Com'è diffusa la pratica di utilizzare una sincronizzazione a bassa granularità in Java?Quanto pesano i monitor Java?

(Esistono ovviamente soluzioni alternative come l'utilizzo di una matrice molto più piccola di oggetti di sincronizzazione, a cui si accederà utilizzando un hash .. Non sto cercando una soluzione pratica, sto cercando un approfondimento).

+1

Gli oggetti Java sono dotati di un blocco leggero integrato. Questa memoria viene utilizzata indipendentemente dal fatto che si blocchi l'oggetto o meno. In breve, Java è progettato e ottimizzato per supportare il blocco di oggetti. –

+0

10 lbs –

risposta

14

Hai già pagato (la maggior parte e in bassa contesa) la penalità per avere i monitor in giro usando Java ... non ha senso non usarli. In particolare nel caso di bassa controversia, sono molto economici (vedere Items 2.1, 2.2, 2.3 here e Item #1 here) e la JVM può ottimizzarli completamente per un numero di casi. Se si utilizza il monitor dell'oggetto solo transitoriamente, la JVM lo renderà "abbastanza grande" (ovvero inizia come bit-flipping, potrebbe espandersi per casi di contesa semplici su un flag atomico impilato allo stack e in conflitto persistente avere un objectmonitor allocato per esso, tutti questi verranno srotolati al caso di low-overhead mentre la contesa diminuisce) e recupererà lo spazio più tardi. Nella misura in cui il blocco su questi oggetti è la "cosa giusta" dal lato delle applicazioni, direi di provarci.

Tuttavia, c'è un odore di design qui. Bloccare su così tanti oggetti non suona bene. Inoltre, se si dispone di condizioni di blocco sequenziali, non si è in grado di ragionare su potenziali punti di stallo. Ti suggerisco di aumentare la tua domanda con maggiori dettagli sull'applicazione, e possiamo chiederci se il blocco su una grande quantità di oggetti sia la cosa giusta.

Questo presentation by Dave Dice fornisce alcune informazioni utili su come funziona la sincronizzazione Java6 e questo blog entry is a treasure trove of sync-on-Java information. Se davvero, davvero ti interessa di quanto "grande" sia una struttura dimonitor degli oggetti completa (entrerà in gioco nel caso conteso), lo code is here. La pagina wiki di HotSpot internals ha anche qualche good in-depth information.

+0

L'utilizzo di Java non significa che abbia già pagato per tutte le possibili hit delle prestazioni in anticipo ... Comunque, questa è una domanda definitiva sul design. Il mio naso C++ avverte un odore, ma non sono usato i profumi Java ... In realtà non sono preoccupato per i deadlock, perché le operazioni sono brevi e semplici. In questi casi, si è tentati di lanciare un "sincronizzato" e di essere al sicuro. Tuttavia sono preoccupato di quanto bene sarà tale scala (so che in Win32 non lo farà, perché gli oggetti del kernel sono costosi). – eran

+0

@eran: capito. Se sappiamo di più sull'applicazione, possiamo approfondire. Ma dato quello che ci hai detto, direi non preoccuparti se non hai un problema di prestazioni misurabili. Nel caso non scontato, hai già pagato quasi tutte le penalità; c'è un piccolo costo di capovolgere un bit già assegnato da qualche parte per monitorenter/exit. Se effettivamente vedi qualche contesa non banale, potresti dover scavare più a fondo. – andersoj

+0

@eran: Se si tratta di un'applicazione ad alte prestazioni per cui sei disposto a investire una seria attenzione di basso livello e vuoi la teoria profonda, dai un'occhiata a Herlihy's Art of Multiprocessor Programming, http: // www. elsevier.com/wps/find/bookdescription.cws_home/714091/descrizione cautela: roba profonda. Ma il codice e l'analisi Java sono disponibili per tutto il contenuto. – andersoj

0

Penso che Collections.synchronizedCollection consenta a un thread di accedere alla raccolta. Tuttavia esiste il problema della creazione di monitor.

6

I mutex Java sono abbastanza economici da poter contenere centinaia di migliaia di oggetti sincronizzati e non notarlo.

Nel caso contrario, un mutex Java consiste di soli 2 bit nella parola flags. La JVM associa solo un oggetto di blocco del sistema operativo pesante con un mutex Java quando il mutex è conteso, quindi rilascia il blocco del sistema operativo quando il mutex è stato chiuso da tutti i thread.

Una panoramica di come mutex Java attuazione può essere trovato in vetrini da 9 a 23 di this presentation da JavaOne 2006.


nota che l'attuazione e le prestazioni del mutex è tale da dipendere venditore/rilascio di Java che stai utilizzando e la piattaforma su cui stai lavorando.

  • Nelle prime versioni di Java, i mutex erano significativamente più costosi.
  • Potrebbero esserci stati dei progressi da quando il documento JavaOne 2006 ... è stato pubblicato o meno.
+0

+1 grande risorsa che non avevo trovato. Vorrei che facessero qualche tentativo di aggregare queste cose in un unico posto. – andersoj

Problemi correlati