2013-08-08 12 views
5

Sto leggendo la sincronizzazione del metodo statico in java. Dove leggo static methods ottiene un blocco su oggetto di java.lang.class. Stavo cercando di capire il concetto di java.lang.class e il suo ruolo nella sincronizzazione del metodo statico e ho queste domande.Qual è l'uso di java.lang.Class e in che modo si riferisce alla sincronizzazione del metodo statico?

  1. stavo leggendo il blog in cui si dice ogni classe in Java ha un'istanza di java.lang.Class e tutte le istanze di una classe condividono questo oggetto. L'istanza di java.lang.Class descrive il tipo di oggetto? Qual è il ruolo di java.lang.Class qui? Come descrive il tipo di oggetto?

  2. In secondo luogo per la sincronizzazione del metodo statico, è necessario ottenere il monitor di java.lang.Class. Perché? Perché abbiamo bisogno di un blocco sul monitor java.lang.Class? Perché non sull'istanza della nostra classe, ad esempio Test (la mia classe personalizzata)?

qualcuno può elaborare su di esso. Sono davvero dispiaciuto perché suona una domanda piuttosto semplice, ma sono abbastanza nuovo in questo concetto.

+0

Potete per favore re-inquadrare l'ultima parte della tua seconda domanda. Ho difficoltà a comprenderlo. –

+0

hi @Ankur, ho rieditato il secondo punto. Per favore fatemi sapere se è chiaro questa volta. – benz

+0

Ogni 'Oggetto' ha una' Classe' che è un 'Oggetto' stesso che ha una' Classe' che sarebbe 'Classe '. Confusione :) – zapl

risposta

4

Spiegazione provvisoria, anche se, ammettiamolo, non è completamente corretto. Per qualsiasi classe C, quando si esegue:

final C c = new C(); 

due Object s sono coinvolti: l'oggetto Class<C> (che viene fornita tramite il contesto di caricamento classe) e l'istanza c. c saprà quale classe è tramite il suo metodo .getClass() (definito in Object).

Il fatto che la parola chiave new sia in grado di stabilire un "backlink" corretto a Class è responsabilità dell'implementazione JVM. Mentre questo è certamente menzionato nel JLS, non posso dire dove ...

Ora, più al punto.

Se si dispone di un metodo dichiarato come:

synchronized void whatever() { someCode(); } 

allora è approssimativamente equivalente a (perché più o meno: vedi sotto):

void whatever() 
{ 
    synchronized(this) { 
     someCode(); 
    } 
} 

Cioè, questo codice è sincronizzato su istanza livello.

Se il metodo è statico tuttavia, questo:

public static synchronized void meh() { someOtherCode(); } 

è più o meno equivalente a (perché più o meno: vedi sotto):

public static void meh() 
{ 
    synchronized(getClass()) { 
     someOtherCode(); 
    } 
} 

Una cosa da notare è che tutti Class oggetti sono single ; indipendentemente dal numero di istanze della classe C creata, .getClass() restituirà sempre lo stesso oggetto Class. Prova questo:

public static void main(final String... args) 
{ 
    final String s1 = "foo"; 
    final String s2 = "bar"; 
    System.out.println(s1.getClass() == s2.getClass()); // true 
} 

aggiunge il fatto che getClass() è equivalente a this.getClass() e si ottiene l'immagine. Class stesso è un Object, obbedisce alle regole del monitor di qualsiasi Object.

E dal momento che qui ci riferiamo sempre lo stesso oggetto, monitorare applicano regole;)

Ora, "più o meno": nel codice scritto sopra, la logica è la stessa; tuttavia, a seconda di come si scrive quel codice, il bytecode potrebbe essere diverso; ma la JIT avrà la sua opinione e alla fine ottimizzerà i percorsi del codice.

+0

nella prima riga, ogni classe in java viene creata da java.lang.Class? – benz

+1

No, non intendo davvero "creato". È la JVM che assegnerà lo spazio necessario per creare la nuova istanza e sarà anche responsabile del "backlink" alla classe di creazione. Questo spiega anche perché è possibile invocare metodi statici da un'istanza di classe, anche se detta istanza è 'null': non è necessario il riferimento all'istanza, ma solo il riferimento alla classe. Non sono sicuro di spiegarmi chiaramente, questo argomento è in definitiva semplice, ma le basi sono difficili da spiegare ... – fge

+0

puoi spiegare le prime due righe della tua risposta. Sono un po 'confuso con loro. Sì, le basi sono difficili da capire. – benz

0

La classe java.lang.Class è una rappresentazione della classe. L'uso principale della classe Class consiste nell'utilizzare la reflection (costruttori e metodi di gettings, ad esempio).

Per questo pensarlo come un meta oggetto ... tutte le istanze di una classe condividono questo meta oggetto.

I progettisti di java hanno scelto che i monitor debbano lavorare sugli oggetti. Per avere un monitor su un metodo statico devi usare il suddetto meta oggetto (o classe).

Penso che questo abbia reso più semplice la progettazione e l'implementazione del monitor per i blocchi sincronizzati. Inoltre, come già detto, la classe java.lang.Class viene utilizzata per la riflessione e quindi è già presente.

1

Ogni oggetto in Java è un esempio di alcuni classe. In aggiunta a ciò ogni classe è un oggetto troppo, quindi è un un'istanza di alcuni classe troppo.

L'istanza di java.lang.Class descrive il tipo di oggetto?

Non esattamente. java.lang.Class è un classe di istanza di classe.

Qual è il ruolo di java.lang.Class qui? Come descrive il tipo di oggetto?

Descrive il tipo di tutti i tipi.

In secondo luogo per la sincronizzazione del metodo statico, è necessario ottenere il monitor di java.lang.Class. Perché? Perché abbiamo bisogno che le sue istanze non bloccino il nostro blocco di classe?

È necessario eseguire la sincronizzazione su alcuni oggetti. I metodi statici non hanno accesso a this, per definizione, quindi l'unica cosa condivisa che rimane è una classe dove sono definiti.

1

In secondo luogo per la sincronizzazione del metodo statico, è necessario ottenere il monitor di java.lang.Class. Perché? Perché abbiamo bisogno di un lock sul monitor java.lang.Class ? Perché non sull'istanza della nostra classe per il test di esempio (la mia classe personalizzata)?

Esistono due modi per sincronizzare i metodi statici. Uno è questo:

static synchronized void methodName(){} 

In questo caso, l'utente non deve preoccupano acquisire la serratura dall'esterno. Internamente tutti i metodi statici di questa classe contrassegnati come sincronizzati dovranno acquisire il blocco sulla sua istanza java.lang.class. In questo caso è molto ovvio che, i blocchi di istanza (new Class()) non possono essere acquisiti qui poiché il metodo è statico e possono esistere metodi statici senza istanze della classe. Anche i metodi statici sono condivisi da tutti gli oggetti di quella classe. Quindi le istanze di questa classe sono fuori discussione.

altro modo è quello di utilizzare blocco sincronizzato all'interno metodo statico:

static void methodName() { 

     synchronized(ClassName.class){ // same as above approach 
     // method defination 
     } 

    synchronized(this){ } // not allowed. compile time error 


    // to get lock of instance of this class you do as shown below. But it is not useful at all. Because every time u acquire different instance. So synchronization is not achieved. 
synchronized(new Class()){ } 
     } 

O

static OtherClass lock = new OtherClass(); 
     static void methodName() { 

      synchronized(lock){ // instance of other class can be used a well 
      // method defination 
      } 
    } 
Problemi correlati