2011-01-22 20 views
7

I metodi che utilizzano solo le variabili locali all'interno subiscono problemi di threading ?. Da qualche parte è stato detto che il metodo con le variabili locali viene copiato in ogni frame dello stack di thread con cui lavorare e non è necessario sincronizzarsi per l'implementazione multithread a meno che non utilizzi riferimenti di classe o riferimenti/variabili statici?In Java, i metodi che non utilizzano variabili statiche o di classe devono essere sincronizzati?

risposta

8

Se il tuo metodo funziona solo su parametri e variabili definite localmente (al contrario di un membro della classe), allora ci sono problemi di sincronizzazione zero di cui preoccuparsi.

Ma ...

Ciò significa nessun tipi riferimento mutabili che si utilizzano must vivere e morire solo nell'ambito di applicazione del metodo. (Tipi di riferimento immutabili non sono un problema qui.) Per esempio, questo non è un problema:

int doSomething(int myParameter) 
{ 
    MyObject working_set = new MyObject(); 
    interim = working_set.doSomethingElse(myParameter); 
    return working_set.doSomethingElseAgain(interim); 
} 

Un'istanza MyObject è creato all'interno del vostro metodo, fa tutto del suo lavoro nel metodo ed è tosse con sangue, in attesa essere abbattuto dal GC quando esci dal tuo metodo.

Questo, d'altra parte, può essere un problema:

int doSomething(int myParameter) 
{ 
    MyObject working_set = new MyObject(); 
    interim = working_set.doSomethingElse(myParameter); 
    another_interim = doSomethingSneaky(working_set); 
    return working_set.doSomethingElseAgain(another_interim); 
} 

A meno che non si sa per certo che cosa sta succedendo nel doSomethingSneaky(), si può avere una necessità per la sincronizzazione da qualche parte. In particolare potrebbe essere necessario eseguire la sincronizzazione sulle operazioni su working_set poiché doSomethingSneaky() potrebbe memorizzare il riferimento all'oggetto locale working_set e passarlo su un altro thread mentre si stanno ancora facendo cose nel metodo o nei metodi di working_set. Qui dovrai essere più difensivo.

Se, ovviamente, lavori solo con tipi primitivi, anche chiamando altri metodi, passando quei valori, non sarà un problema.

+0

"qualsiasi tipo di riferimento" dovrebbe probabilmente essere "qualsiasi tipo di riferimento _mutable_" ... gli oggetti non modificabili non sono un problema. – ColinD

+0

Poliziotto equo. Lo cambierò. –

0

Non è necessario preoccuparsi delle variabili locali. Le variabili di istanza sono comunque qualcosa di cui preoccuparsi.

4

I metodi che utilizzano solo variabili locali all'interno, non presentano problemi di threading?

vero in un senso molto semplicistico, ma permette di essere chiaro - credo che questo è vero solo se:

  • tale metodo utilizza solo le variabili locali che sono primitive o riferimenti a casi mutevoli che non possono altrimenti si può accedere al di fuori del metodo con qualsiasi altro mezzo.

  • tale metodo richiama solo metodi che sono thread-safe.

Alcuni modi queste regole potrebbero essere violati:

  • Una variabile locale potrebbe essere inizializzato per puntare a un oggetto che è accessibile al di fuori del metodo anche. Ad esempio, una variabile locale potrebbe puntare a un singleton (Foo bar = Foo.getSingleton()).

  • Un'istanza locale detenuta da una variabile locale potrebbe "perdere" se l'istanza viene passata come argomento a un metodo esterno che mantiene un riferimento all'istanza.

  • Una classe senza variabili di istanza e con un solo metodo senza variabili locali può ancora chiamare il metodo statico di un'altra classe che non è thread-safe.

1

La domanda è molto generica, quindi per favore non aspettatevi alcuna specificità dalla mia risposta.

1_ È necessario prestare maggiore attenzione ai metodi statici rispetto ai metodi di istanza.

2_ @Justmycorrectopinion è corretto, ma alcuni dei termini descritti devono essere più elaborati per essere perfetti. (Anche se il metodo statico funziona solo su variabili locali, esiste ancora la possibilità di condizioni di gara.)

3_ Per me ci sono semplici regole che mi hanno aiutato ad analizzare la sicurezza dei thread.

Capire se ogni componente incapsulato al suo interno è condivisibile o meno. Quindi la soluzione più semplice è ridurre l'ambito di tutte le variabili e aumentare solo l'ambito se è assolutamente necessario e se il componente esegue la mutazione su un oggetto, di solito non è thread-safe.

4_ Utilizzare il supporto degli utensili per eseguire l'analisi del codice statico sulla sicurezza del filo. (L'idea ha un plugin per il checkthread).

5_ Non utilizzare mai il metodo statico per eseguire la mutazione dell'oggetto. Se la chiamata a una variabile statica causa una mutazione dell'oggetto, lo sviluppatore sta semplicemente aggirando OOPS.

6_ Documentare sempre la sicurezza del filo. Ricorda che alcuni metodi potrebbero non aver bisogno di essere sincronizzati durante lo sviluppo, ma possono essere resi molto poco sicuri.

7_ Ultimo ma probabilmente il mio punto più importante, assicurati che la maggior parte dei tuoi oggetti siano immutabili. Nella mia esperienza, la maggior parte delle volte, non ho mai dovuto rendere mutevoli molti dei miei oggetti. (In rari casi in cui lo stato dell'oggetto deve essere modificato, la copia difensiva/Creazione nuovo oggetto è quasi sempre migliore.)

Problemi correlati