417 votes

bloc synchronisé vs synchronisé méthode ?

Quelqu'un peut me dire l’avantage de la méthode synchronisée sur bloc synchronisé avec un exemple ?

445voto

OscarRyz Points 82553

Quelqu'un peut-il me dire l'avantage de la méthode synchronisée sur bloc synchronisé avec un exemple?Merci.

Il n'est pas un avantage évident de l'utilisation de la méthode synchronisée sur le bloc.

Peut-être le seul ( mais je n'appellerais pas cela de l'avantage ) est que vous n'avez pas besoin d'inclure l'objet de référence this.

Méthode:

public synchronized void method() { // blocks "this" from here.... 
    ...
    ...
    ...
} // to here

Bloc

public void method() { 
    synchronized( this ) { // blocks "this" from here .... 
        ....
        ....
        ....
    }  /// to here...
}

Voir? aucun avantage.

Les blocs n' ont des avantages sur les méthodes, la plupart en raison de la flexibilité, car vous pouvez utiliser un autre objet que la serrure tandis que la synchronisation de la méthode de verrouillage de la classe complète.

Comparer:

// locks the whole object
... 
private synchronized void someInputRelatedWork() {
    ... 
}
private synchronized void someOutputRelatedWork() {
    ... 
}

Vs.

// Using specific locks
Object inputLock = new Object();
Object outputLock = new Object();

private void someInputRelatedWork() {
    synchronize(inputLock) { 
        ... 
    } 
}
private void someOutputRelatedWork() {
    synchronize(outputLock) { 
        ... 
    }
}

Aussi, si la méthode se développe, vous pouvez toujours garder synchronisés section séparée:

 private void method() {
     ... code here
     ... code here
     ... code here
    synchronized( lock ) { 
        ...very few lines of code here
    }
     ... code here
     ... code here
     ... code here
     ... code here
}

143voto

jcrossley3 Points 6297

La seule vraie différence est que, en parallèle, un bloc peut choisir quel objet il se synchronise sur. Une méthode synchronisée ne pouvez utiliser 'this' (ou de la Classe correspondante exemple, pour une synchronisé méthode de classe). Par exemple, ils sont sémantiquement équivalentes:

synchronized void foo() {
  ...
}

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

Ce dernier est plus flexible car il peut rivaliser pour les associés de verrouillage de tout objet, souvent un membre de la variable. Il est également plus précis parce que vous pourriez avoir simultanées de l'exécution du code avant et après le bloc, mais toujours à l'intérieur de la méthode. Bien sûr, vous pourriez tout aussi bien utiliser une méthode synchronisée par le refactoring du code simultané dans un espace non-synchronisé méthodes. Utilisation selon ce qui rend le code plus compréhensible.

77voto

iny Points 3925

Méthode Synchronisée

Pour:

  • Votre IDE peut indiquer les méthodes synchronisées.
  • La syntaxe est plus compact.
  • Les Forces de diviser les blocs synchronisés pour séparer les méthodes.

Inconvénients:

  • Synchronise cela et permet à des étrangers de se synchroniser à elle aussi.
  • Il est plus difficile de passer le code en dehors de la synchronisation de bloc.

Synchronisé bloc

Pour:

  • Permet d'utiliser une variable privée de la serrure et ainsi de forcer la serrure de rester à l'intérieur de la classe.
  • Synchronisé les blocs peuvent être trouvés par la recherche de références à la variable.

Inconvénients:

  • La syntaxe est plus complexe et donc rend le code plus difficile à lire.

Personnellement, je préfère utiliser des méthodes synchronisées avec les cours consacrés uniquement à la chose devant de la synchronisation. Une telle classe doit être aussi petite que possible et il devrait donc être facile de passer en revue la synchronisation. D'autres ne devraient pas besoin de se soucier de la synchronisation.

36voto

cdecker Points 1371

La différence principale est que si vous utilisez un bloc synchronisé vous pouvez verrouiller sur un objet autre que ce qui permet d'être beaucoup plus souple.

Supposons que vous disposez d'un message de la file d'attente et de multiples message des producteurs et des consommateurs. Nous ne voulons pas les producteurs à interférer les uns avec les autres, mais les consommateurs doivent être en mesure de récupérer des messages sans avoir à attendre pour les producteurs. Afin que nous venons de créer un objet

Object writeLock = new Object();

Et à partir de maintenant, chaque fois que des producteurs veut ajouter un nouveau message nous venons de verrou sur:

synchronized(writeLock){
  // do something
}

Ainsi, les consommateurs peuvent toujours lire, et les producteurs seront verrouillés.

31voto

sudheer Points 211

Méthode synchronisée

Synchronisé méthodes ont deux effets.
Tout d'abord, lorsqu'un thread est en cours d'exécution d'une méthode synchronisée pour un objet, tous les autres threads qui l'invoque, synchronisé méthodes pour le même objet (bloc de suspendre l'exécution) jusqu'à ce que le premier thread est terminé avec l'objet.

Deuxièmement, lorsqu'une méthode synchronisée sorties, il établit automatiquement un passe-avant relation avec toute demande subséquente de l'invocation d'une méthode synchronisée pour le même objet. Cela garantit que les modifications de l'état de l'objet sont visibles par tous les threads.

Notez que les constructeurs ne peuvent pas être synchronisés - à l'aide de la synchronisation de mot-clé avec un constructeur est une erreur de syntaxe. La synchronisation des constructeurs n'a pas de sens, parce que seul le thread qui crée un objet devrait y avoir accès alors qu'il est en cours de construction.

Synchronisé Déclaration

Contrairement aux méthodes synchronisées, synchronisé instructions doivent préciser l'objet qui fournit la valeur intrinsèque de verrouillage: le Plus souvent je l'utilise pour synchroniser l'accès à une liste ou sur la carte mais je ne veux pas bloquer l'accès à toutes les méthodes de l'objet.

Q: Intrinsèque de Serrures et de Synchronisation La synchronisation est construit autour d'un interne de l'entité connue sous le nom intrinsèques de verrouillage ou de moniteur de verrouillage. (La spécification de l'API fait souvent référence à cette entité simplement comme un "moniteur".) Intrinsèque des serrures de jouer un rôle dans les deux aspects de la synchronisation: l'application d'un accès exclusif à l'état d'un objet et de l'établissement de-passe-avant les relations qui sont essentielles à la visibilité.

Chaque objet a une valeur intrinsèque de verrouillage associés. Par convention, un thread qui doit exclusive et cohérente de l'accès à un objet de champs doit acquérir l'objet intrinsèque de verrouillage avant d'accéder, puis relâchez la valeur intrinsèque de verrouillage quand il est fait avec eux. On dit qu'un fil propre intrinsèques de verrouillage entre le moment où elle a acquis la serrure et libéré de la serrure. Aussi longtemps qu'un thread possède une valeur intrinsèque de serrure, aucun autre thread ne peut acquérir la même serrure. L'autre fil se bloquer lorsqu'il tente d'acquérir le verrou.

package test;

public class SynchTest implements Runnable {  
    private int c = 0;

    public static void main(String[] args) {
        new SynchTest().test();
    }

    public void test() {
        // Create the object with the run() method
        Runnable runnable = new SynchTest();
        Runnable runnable2 = new SynchTest();
        // Create the thread supplying it with the runnable object
        Thread thread = new Thread(runnable,"thread-1");
        Thread thread2 = new Thread(runnable,"thread-2");
//      Here the key point is passing same object, if you pass runnable2 for thread2,
//      then its not applicable for synchronization test and that wont give expected
//      output Synchronization method means "it is not possible for two invocations
//      of synchronized methods on the same object to interleave"

        // Start the thread
        thread.start();
        thread2.start();
    }

    public synchronized  void increment() {
        System.out.println("Begin thread " + Thread.currentThread().getName());
        System.out.println(this.hashCode() + "Value of C = " + c);
//      If we uncomment this for synchronized block, then the result would be different
//      synchronized(this) {
            for (int i = 0; i < 9999999; i++) {
                c += i;
            }
//      }
        System.out.println("End thread " + Thread.currentThread().getName());
    }

//    public synchronized void decrement() {
//        System.out.println("Decrement " + Thread.currentThread().getName());
//    }

    public int value() {
        return c;
    }

    @Override
    public void run() {
        this.increment();
    }
}

Contre-vérifier les différentes sorties avec méthode synchronisée, bloc et sans synchronisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X