Nous allons prendre quelques exemples pour voir si une méthode statique est Thread-Safe ou non.
Exemple 1 :
public static String concat (String st1, String str2) {
return str1 + str2
}
La méthode ci-dessus est sans risque pour les threads.
Nous allons maintenant voir un autre exemple qui n'est pas sûr pour les threads.
Exemple 2 :
public static void concat(StringBuilder result, StringBuilder sb, StringBuilder sb1) {
result.append(sb);
result.append(sb1);
}
Si vous voyez, les deux méthodes sont très primitives, mais l'une d'entre elles est sûre et l'autre ne l'est pas. Pourquoi ? Quelle est la différence entre les deux ?
Les méthodes statiques dans les utilitaires sont-elles susceptibles de ne pas être sûres pour les threads ? Beaucoup de questions, n'est-ce pas ?
Tout dépend maintenant de la manière dont vous implémentez la méthode et du type d'objets que vous utilisez dans votre méthode. Utilisez-vous des objets sécurisés ? Ces objets / classes sont-ils mutables ?
Comme le montre l'exemple 1, les arguments de la méthode concat sont du type String, qui est immuable et transmis par valeur, de sorte que cette méthode est totalement sûre pour les threads.
Dans l'exemple 2, les arguments sont de type StringBuilder, qui sont mutables, de sorte qu'un autre thread peut modifier la valeur de StringBuilder, ce qui fait que cette méthode n'est potentiellement pas sûre pour les threads.
Là encore, ce n'est pas tout à fait vrai. Si vous appelez cette méthode utilitaire avec des variables locales, vous n'aurez jamais de problème lié à la sécurité des threads. Parce que chaque thread utilise sa propre copie des variables locales, vous ne rencontrerez jamais de problèmes liés à la sécurité des threads. Mais cela dépasse le cadre de la méthode statique ci-dessus. Cela dépend de la fonction / du programme appelant.
Aujourd'hui, les méthodes statiques dans les classes utilitaires sont en quelque sorte une pratique normale. Comment pouvons-nous l'éviter ? Dans l'exemple 2, je modifie le premier paramètre. Maintenant, si vous voulez rendre cette méthode vraiment sûre pour les threads, il y a une chose simple que vous pouvez faire. Soit vous utilisez des variables / objets non modifiables, soit vous ne changez pas / ne modifiez pas les paramètres de la méthode.
Dans l'exemple 2, nous avons déjà utilisé StringBuilder qui est mutable. Vous pouvez donc modifier l'implémentation pour rendre la méthode statique sûre pour les threads comme suit :
public static String concat1(StringBuilder sb, StringBuilder sb1) {
StringBuilder result = new StringBuilder();
result.append(sb);
result.append(sb1);
return result.toString();
}
Si vous utilisez des objets immuables et des variables locales, vous êtes à mille lieues des problèmes liés à la sécurité des threads.
Extrait de l'article( https://nikhilsidhaye.wordpress.com/2016/07/29/is-static-method-in-util-class-threadsafe/ )Merci Nikhil Sidhaye pour ce simple article
12 votes
Pourquoi un vote négatif et une demande de fermeture ? Est-ce une mauvaise question ?
0 votes
Avez-vous envisagé de rendre cette méthode statique
synchronized
?16 votes
@AndrewLogvinov oui j'y ai pensé. Mais je ne veux pas rendre une méthode synchronisée sans savoir pourquoi je le fais. Dans quelles situations devrions-nous rendre une méthode statique synchronisée ?
3 votes
@TapasBose La question du dernier commentaire peut probablement donner lieu à un livre ou deux. Je recommanderais Concurrence Java en pratique .
2 votes
Vous devez synchroniser les méthodes (statiques et d'instance) qui accèdent aux variables mutables. Dans le cas des classes utilitaires, je n'en vois pas l'utilité puisqu'elles devraient être sans état.