web-dev-qa-db-fra.com

Est-il raisonnable de synchroniser sur une variable locale?

Dans le modèle de mémoire Java, nous savons que chaque thread a sa propre pile de threads et que les variables locales sont placées dans la pile de threads de chaque thread. 

Et que les autres threads ne peuvent pas accéder à ces variables locales.

Alors, dans quel cas, devrions-nous synchroniser sur des variables locales?

8
NingLee

Il y a deux situations:

  1. La variable locale est d'un type primitif tel que int ou double.
  2. La variable locale est d'un type de référence tel que ArrayList.

Dans le premier cas, vous ne pouvez pas synchroniser, car vous ne pouvez synchroniser que sur des objets (pointés par des variables de type référence).

Dans le second cas, tout dépend de ce que la variable locale indique. S'il pointe vers un objet auquel d'autres threads (peuvent également pointer), vous devez vous assurer que votre code est correctement synchronisé.

Exemples: vous avez affecté la variable locale à partir d'un champ static ou d'instance, ou vous avez obtenu l'objet à partir d'une collection partagée.

Cependant, si l'objet a été créé dans votre thread et affecté uniquement à cette variable locale, et que vous ne donnez jamais de référence à celle-ci depuis votre thread vers un autre thread, et que l'implémentation des objets elle-même ne donne pas de références, ne vous inquiétez pas de la synchronisation.

10
Erwin Bolwidt

Vous parlez du cas ci-dessous:

public class MyClass {
    public void myMethod() {
        //Assume Customer is a Class
        Customer customer = getMyCustomer();
        synchronized(customer) {
            //only one thread at a time can access customer object
              which ever holds the lock
        }
    }
}

Dans le code ci-dessus,customer est une variable de référence locale, mais vous utilisez toujours un bloc synchronisé pour limiter l'accès à l'objet customer pointe vers ( par un seul thread à la fois ).

Dans le modèle de mémoire Java, les objets vivent dans le tas (même si les références sont locales à un thread qui vit dans une pile) et la synchronisation consiste à restreindre l'accès à un objet sur le tas de exactement un thread à la fois. 

En bref, lorsque vous dites variable locale (non primitive), seule la référence est locale, mais pas l'objet réel lui-même, c'est-à-dire qu'il fait référence à un objet sur le tas auquel de nombreux autres threads peuvent accéder. Pour cette raison, vous avez besoin d'une synchronisation sur l'objet pour qu'un seul thread ne puisse accéder à cet objet à la fois.

12
developer

Oui, cela a du sens lorsque la variable locale est utilisée pour synchroniser l'accès à un bloc de code à partir de threads définis et créés dans la même méthode que la variable locale.

2
Boris Pavlović