2012-12-17 16 views
35

Esiste un modo generale o di uscita di regole con cui possiamo garantire la sicurezza del thread dei metodi statici utilizzati in modo specifico in varie classi di Utility di qualsiasi applicazione. Qui voglio sottolineare in modo specifico la sicurezza del thread delle applicazioni Web.Come garantire la sicurezza del thread del metodo statico di utilità?

È noto che i metodi statici con oggetti immutabili come parametri sono thread-safe e gli oggetti mutabili no.

Se si dispone di un metodo di utilità per alcune manipolazioni di java.util.Date e tale metodo accetta un'istanza di java.util.Date, questo metodo non sarebbe thread-safe. Quindi come renderlo thread-safe senza cambiare il modo di passare i parametri?

public class DateUtils { 

    public static Date getNormalizeDate(Date date) { 
     // some operations 
    } 
} 

Inoltre è possibile modificare la classe javax.faces.context.FacesContext? È thread-safe passare un'istanza di questa classe a tale metodo di utilità statica?

Questo elenco di classi, le cui istanze possono essere o non possono essere passate come parametri, potrebbe essere lungo; quindi quali punti dovremmo tenere a mente durante la scrittura di codici di tali classi di utilità?

+2

Perché votare e una richiesta di chiusura? È una domanda sbagliata? –

+0

Hai pensato di rendere 'sincronizzato 'questo metodo statico? –

+6

@AndrewLogvinov sì, ho pensato. Ma non voglio rendere sincronizzato un metodo senza sapere perché lo sto facendo. In quali situazioni dovremmo sincronizzare un metodo statico? –

risposta

46

È noto che i metodi statici con oggetti immutabili come parametri non sono thread-safe e gli oggetti mutabili no.

Vorrei contestarlo. Gli argomenti passati a un metodo sono archiviati su uno stack, che è un idioma per thread.

Se il parametro è un oggetto mutabile come Date, è necessario assicurarsi che altri thread non lo stiano modificando contemporaneamente altrove. Ma questa è una questione diversa non correlata alla sicurezza del thread del tuo metodo.

Il metodo che hai postato è thread-safe. Mantiene nessuno stato e opera solo sui suoi argomenti.

Si consiglia vivamente di leggere Java Concurrency in Practice o un libro simile dedicato alla sicurezza dei thread in Java. È un argomento complesso che non può essere affrontato in modo appropriato attraverso alcune risposte StackOverflow.

+0

Ottima risposta, grazie – Keerthivasan

3

Si consiglia di creare una copia dell'oggetto (mutabile) non appena viene avviato il metodo e utilizzare la copia anziché il parametro originale.

Qualcosa di simile

public static Date getNormalizeDate(Date date) { 
    Date input = new Date(date.getTime()); 
    // ... 
} 
+2

Suona bene per Data, ma non sarà possibile per gli oggetti personalizzati, specialmente se si tratta di un oggetto personalizzato di terze parti che non può modificare. –

11

Poiché la classe non possiede variabili membro, il metodo è senza stato (si utilizza solo variabili locali e l'argomento) e, pertanto, è thread-safe.

Il codice che lo chiama potrebbe non essere thread-safe ma questa è un'altra discussione. Ad esempio, Data non è thread-safe, se il codice chiamante legge una data che è stata scritta da un altro thread, è necessario utilizzare la sincronizzazione corretta nel codice di scrittura e lettura della data.

4

Data la struttura della JVM, le variabili locali, i parametri del metodo e i valori di ritorno sono intrinsecamente "thread-safe". Ma le variabili di istanza e le variabili di classe saranno sicure per i thread solo se si progetta la classe in modo appropriato. altro here

0

Ecco come ci penso: immagina un CampSite (è un metodo statico).Come camper, posso portare un mucchio di oggetti nel mio zaino (sono argomenti passati in pila). Il CampSite mi fornisce un posto dove mettere la mia tenda e il mio campstove, ecc., Ma se l'unica cosa che CampSite fa è permettermi di modificare i miei oggetti, allora è sicuro. CampSite può anche creare oggetti dal nulla (FirePit firepit = new FirePit();), che vengono anche creati nello stack.

In qualsiasi momento posso sparire con tutti i miei oggetti nel mio ruckstack e uno qualsiasi degli altri campeggiatori può apparire, facendo esattamente quello che stavano facendo l'ultima volta che sono scomparsi. Diversi thread in questo CampSite non avranno accesso agli oggetti nello stack creati da CampSite in altri thread.

Dire che c'è solo un campStove (un oggetto singolo di CampStove, non istanze separate). Se con un po 'di immaginazione sto condividendo un oggetto CampStove, allora ci sono considerazioni multi-threading. Non voglio accendere il mio campStove, scomparire e riapparire dopo che un altro campeggiatore l'ha spento: controllerei per sempre se il mio hot dog fosse finito e non lo sarebbe mai stato. Dovresti mettere un po 'di sincronizzazione da qualche parte ... nella classe CampStove, nel metodo che stava chiamando CampSite o nello stesso CampSite ... ma come Duncan Jones dice "è diverso".

Si noti che anche se ci si accampasse in istanze separate di non - oggetti CampSite statici, la condivisione di un campStove avrebbe le stesse considerazioni multi-thread.