Question Java deux méthodes synchronisées dans une instance


considérez le code suivant:

public class SynchronizedCounter extends Thread {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public void run() {
        for(;;)
            increment();
    }
}

static void main(String[] args) {
    SynchronizedCounter counter = new SynchronizedCounter();
    counter.start();
    for(;;)
        counter.decrement();
}

cela signifie-t-il que incrément() et décrémenter () les méthodes attendront L'un et l'autre pour finir ou pas?

MODIFIER: et ça n'attend pas?

static void main(String[] args) {
    SynchronizedCounter counter1 = new SynchronizedCounter();
    SynchronizedCounter counter2 = new SynchronizedCounter();
    counter1.start();
    for(;;)
        counter2.decrement();
}

12
2018-05-13 11:39


origine


Réponses:


Oui le synchronized Le mot-clé est un raccourci pour:

synchronized(this) {
  //...
}

Les deux méthodes se bloquent donc efficacement sur le même objet mutex. Si vous voulez qu'ils soient indépendants l'un de l'autre (ce qui est une mauvaise idée dans cet exemple car ils accèdent tous deux à la même valeur), voir Objets de classe privée à verrouillage d'objet - meilleures pratiques? (Java).

BTW votre SynchronizedCounter devrait mettre en œuvre Runnable plutôt que de prolonger un Thread puisque vous le transmettez au constructeur d'un autre thread - maintenant c'est un peu déroutant.


13
2018-05-13 11:45



le le verrou est toujours sur l'objet entier. Si l'un d'entre eux est le synchronized les membres sont accessibles.

Dans votre premier exemple, il y a deux threads contester pour le même  counter objet, celui que vous avez commencé explicitement (qui appelle le increment() méthode en boucle infinie) et l'autre thread est le thread principal (qui appelle le decrement() infiniment).

Dans le deuxième exemple, il y a deux objets créés counter1 et counter2. Celles-ci auront leurs propres serrures indépendantes les unes des autres. Le verrouillage d'un objet n'affecte pas les autres threads d'accès à un autre objet. Les deux threads (le thread explicite et le thread principal) acquièrent le verrouillage sur deux objets différents et donc dans pas de dispute.


6
2018-05-13 12:03



Cela signifie-t-il que les méthodes increment () et decrement () vont s’attendre pour finir ou non?

NON, cela signifie qu'aucun autre thread ne pourra appeler increment () et decrement () quand un thread est en leur sein. Pour être complet, un autre thread n'a pu exécuter aucune méthode synchronisée de cette instance / objet

Vous pouvez appeler n'importe quelle autre méthode synchronisée à partir d'une méthode synchronisée sans verrou sur la même instance / le même objet


1
2018-05-13 18:38