Sécurité des threads et variables locales

Si j’ai une variable locale comme celle-ci:

Increment() { int i = getFromDb(); // get count for a customer from db }; 

Et ceci est une classe d’instance qui s’incrémente (chaque fois qu’un client – un object d’instance – effectue un achat), cette variable thread est-elle sécurisée? J’entends dire que les variables locales sont thread-safe car chaque thread a sa propre stack, etc.

De plus, ai-je raison de penser que cette variable est un état partagé? Ce qui me manque dans le département de la pensée, c’est que cette variable travaillera avec différents objects client (par exemple, John, Paul, etc.), donc elle est thread-safe, mais c’est une pensée imparfaite et un peu d’inexpérience dans la programmation concurrente. Cela semble très naïf, mais je n’ai pas beaucoup d’expérience dans le codage simultané, contrairement au codage synchrone en général.

EDIT: De plus, l’appel de la fonction getFromDb () ne fait pas partie de la question et je ne m’attends pas à ce que quelqu’un devine la sécurité de son thread, car il s’agit simplement d’un appel pour indiquer que la valeur est affectée par une fonction qui extrait les données de la firebase database. . 🙂

EDIT 2: En outre, la sécurité des threads de getFromDb est garantie car il effectue uniquement des opérations de lecture.

i est déclaré en tant que variable locale (méthode), il n’existe donc normalement que dans la stack-cadre de Increment() – alors oui, i est thread-safe … (bien que je ne puisse pas commenter getFromDb ).

sauf si:

  • Increment est un bloc d’iterator (c.-à-d. yield return utilise un yield return ou yield break )
  • i est utilisé dans une méthode anonyme ( delegate { i = i + 1;} ) ou lambda ( foo => {i=i+foo;}

Dans les deux scénarios ci-dessus, il existe des cas où il peut être exposé en dehors de la stack. Mais je doute que vous le fassiez non plus.

Notez que les champs (variables de la classe) ne sont pas thread-safe, car ils sont exposés de manière sortingviale à d’autres threads. Cela est encore plus visible avec static champs static , car tous les threads partagent automatiquement le même champ (à l’exception des champs statiques de thread).

Votre relevé comporte deux parties distinctes: un appel de fonction et une affectation.

L’affectation est thread-safe, car la variable est locale. Chaque appel différent de cette méthode obtiendra sa propre version de la variable locale, chacune étant stockée dans un cadre de stack différent, à un emplacement différent en mémoire.

L’appel à getFromDb () peut ou non être threadsafe – en fonction de son implémentation.

Tant que la variable est locale à la méthode, elle est thread-safe. S’il s’agissait d’une variable statique, ce ne serait pas par défaut.

 class Example { static int var1; //not thread-safe public void Method1() { int var2; //thread-safe } } 

Alors que votre int i est thread-safe, votre cas entier est probablement pas thread-safe. Comme vous l’avez dit, votre int est thread-safe car chaque thread a sa propre trace de stack et donc chaque thread a son propre i. Cependant, tous vos threads partagent la même firebase database. Par conséquent, vos access à la firebase database ne sont pas thread-safe. Vous devez synchroniser correctement vos access à la firebase database pour vous assurer que chaque thread ne verra la firebase database qu’au bon moment.

Comme d’habitude avec l’access simultané et le multithreading, vous n’avez pas besoin de synchroniser votre firebase database si vous ne lisez que des informations. Vous devez synchroniser dès que deux threads essaieront de lire / écrire le même ensemble d’informations à partir de votre firebase database.

Je serai “thread safe” car chaque thread aura sa propre copie de i sur la stack, comme vous le suggérez. La vraie question sera: le contenu du thread getFromDb () est-il sécurisé?

i est une variable locale, donc ce n’est pas un état partagé.

Si votre getFromDb () lit, par exemple, une séquence oracle ou un champ d’auto-incrémentation de serveur SQL, la firebase database se charge de la synchronisation (dans la plupart des scénarios, à l’exclusion des bases de données de réplication / dissortingbuées) afin que vous puissiez probablement renvoyer le résultat en toute sécurité fil. En d’autres termes, la firebase database garantit que chaque appel à getFromDB () recevra une valeur différente.

La sécurité des threads représente généralement un peu de travail. Changer le type d’une variable vous apportera rarement la sécurité des threads, car cela dépend de la manière dont vos threads accéderont aux données. Vous pouvez éviter quelques maux de tête en retravaillant votre algorithme afin qu’il utilise une queue avec laquelle tous les consommateurs se synchronisent au lieu d’essayer d’orchestrer une série de verrous / moniteurs. Ou mieux encore, libérez l’algorithme si possible.

i est thread safe syntaxiquement. Mais lorsque vous affectez les valeurs de la variable d’instance, méthode par exemple, à renvoyer la valeur à i, les données partagées sont manipulées par plusieurs threads.