Eventi thread-safe - blocco su riferimenti privati

1

Leggevo di delegati ed eventi sulla questa pagina web per avere una migliore comprensione di loro e di come si relazionano a vicenda. Durante la lettura, ho trovato questa affermazione:

That goes against the principle of locking on privately held references to avoid accidental deadlocks.

L'autore si riferiva a un blocco con un riferimento a questo oggetto nelle operazioni di aggiunta e rimozione di un evento.

Non sono stati forniti ulteriori dettagli sul principio a cui si stava riferendo, forse perché dovrebbe essere ovvio. In ogni caso, non era ovvio per me. Qualcuno può illuminarmi su questo e fornire ulteriori dettagli?

    
posta jaromey 16.12.2015 - 08:53
fonte

2 risposte

5

Bene, se leggi qualche riga in più, sembra che alcuni metodi eseguano un'operazione di blocco, ma non sai quale oggetto viene usato per il blocco. E questo è un problema molto diverso, perché tu non puoi bloccare lo stesso oggetto se questo è ciò che vuoi fare. Tutti i codici che cercano di proteggere gli stessi dati devono ovviamente usare lo stesso blocco .

Per quanto riguarda il deadlock, sì, potrebbe essere un problema. Thread 1 blocchi sull'oggetto A, quindi sull'oggetto B. Thread 2 blocchi sull'oggetto B, quindi esegue un'operazione innocente. Dovrebbe andare bene, giusto? Ma se l'operazione dall'aspetto innocente si blocca sull'oggetto A, hai una situazione di stallo.

Cosa c'entra "privatamente" con qualsiasi cosa? Thread 1 e Thread 2 possono solo deadlock se il lock la stessa variabile. Se "operazione di ricerca innocua" blocca una variabile che è tenuta privatamente e non accessibile ad altro codice, allora non si entrerà in un deadlock.

    
risposta data 16.12.2015 - 10:01
fonte
1

Primo - deadlock. Questo è quando si ha un thread all'interno di un lock, cercando di bloccare qualcos'altro, e che qualcos'altro è bloccato da un altro thread in attesa del lock del thread originale. Si siedono lì in attesa che finisca l'altro thread, ma nessuno dei due può farlo. Cattivi tempi.

Il problema è che ogni istanza di un oggetto può servire come contesto di un lucchetto. Bloccando su istanze private, sei (ragionevolmente) sicuro che solo il codice in quella classe può bloccare quell'istanza, quindi puoi limitare l'analisi per vedere se quel codice può deadlock.

Bloccando su this , il codice esterno della classe potrebbe anche bloccare quell'istanza, rendendo molto più difficile individuare potenziali scenari di deadlock nella base di codice, e impossibile una volta che si considerano esterni consumatori del tuo codice.

Detto questo, trovo che questa best practice sia un po 'un culto del cargo. Il blocco manuale delle variabili è abbastanza comune, e molto spesso la necessità di bloccare è intorno a un ambito di classe. Creare un nuovo object solo per bloccarlo non è intuitivo e molto spesso eccessivo.

Tuttavia, è molto importante capire perché questo genere di cose viene fatto per quelle volte in cui non è eccessivo.

    
risposta data 16.12.2015 - 21:04
fonte

Leggi altre domande sui tag