Java >> Java tutorial >  >> Tag >> synchronized

Hvorfor kan en abstrakt metode ikke synkroniseres?

Kommentaren om ikke at kunne instansiere den abstrakte klasse er skrald. I betragtning af at det skal være en instansmetode for at være abstrakt, er det bestemt en reference, som kunne låses fast. Konkrete metoder i abstrakte klasser kan stadig henvise til this . Det betyder dog stadig ikke, at abstrakte klasser skal kunne synkroniseres.

Hvorvidt en metode er synkroniseret eller ej, er en implementeringsdetalje af metoden. Synkronisering er ikke angivet nogensteds som en deklarativ kontrakt - det er heller ikke sådan, at du kan synkronisere i grænseflader.

Hvordan en klasse implementerer den trådsikkerhedsgaranti, den giver, er op til den. Hvis en abstrakt klasse ønsker at mandat en bestemt tilgang, bør den bruge skabelonmetodemønsteret:

// I hate synchronizing on "this"
private final Object lock = new Object();

public final void foo() {
    synchronized(lock) {
        fooImpl();
    }
}

protected abstract void fooImpl();

Det er dog ret farligt i sig selv, i betragtning af at det effektivt kalder "ukendt" kode i en lås, som er en opskrift på blokeringer osv.


Låseadfærd bør ikke specificeres ved hjælp af abstrakte metoder eller grænseflademetoder, fordi det ikke bør være en del af kontrakten.

Sandsynligvis var ideen, at låseadfærd grundlæggende er en del af implementeringen -- forskellige implementeringer vil gerne udføre låsning forskelligt -- og det ville være kontraproduktivt at specificere det på det abstraktionsniveau.

Husk søgeordet synchronized er specifikt til implementering af implicit låsning (erhvervelse af låsen på objektet, som instansmetoden kaldes på), og der er måder at udføre låsning på ved hjælp af alternativer som ReentrantLock, hvor dette nøgleord ikke er anvendeligt, eller muligvis for at bruge CAS eller på anden måde undgå låsning i det hele taget.


synchronized void foo()
{
    body
}

er defineret til at svare til

void foo()
{ 
    synchronized(this)
    {
        body
    }
}

(hvis statisk, synkroniseret på klassen i stedet for this )

Da en abstrakt metode ikke har nogen krop, synchronized søgeord på metoden er udefineret.


Java tag