90 votes

Comment assurer la sécurité des threads d'une méthode statique utilitaire ?

Existe-t-il un moyen général ou des règles permettant d'assurer la sécurité des méthodes statiques utilisées dans les différentes classes d'utilitaires de n'importe quelle application ? Je souhaite ici mettre l'accent sur la sécurité des threads dans les applications Web.

Il est bien connu que les méthodes statiques avec des objets immuables comme paramètres sont sûres pour les threads et que les objets mutables ne le sont pas.

Si j'ai une méthode utilitaire pour une manipulation de java.util.Date et cette méthode accepte une instance de java.util.Date cette méthode ne serait pas sûre pour les threads. Alors comment la rendre thread safe sans changer la façon de passer les paramètres ?

public class DateUtils {

    public static Date getNormalizeDate(Date date) {
        // some operations
    }   
}

Il y a aussi la classe javax.faces.context.FacesContext mutable ? Est-il possible de passer une instance de cette classe à une telle méthode utilitaire statique ?

La liste des classes dont les instances peuvent ou ne peuvent pas être transmises en tant que paramètres pourrait être longue ; quels sont donc les points à garder à l'esprit lors de l'écriture des codes de ces classes utilitaires ?

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 ?

7voto

PMorganCA Points 151

Voici comment je vois les choses : imaginez un Camping (c'est une méthode statique). En tant que campeur, je peux apporter un tas d'objets dans mon sac à dos (ce sont des arguments passés sur la pile). Le Camping me fournit un endroit pour mettre ma tente et mon réchaud, etc., mais si la seule chose que fait le Camping est de me permettre de modifier mes propres objets, alors il est threadsafe. Le camping peut même créer des objets à partir de rien ( FirePit firepit = new FirePit(); ), qui sont également créés sur la pile.

À tout moment, je peux disparaître avec tous mes objets dans mon sac à dos et l'un des autres campeurs peut apparaître, faisant exactement ce qu'il faisait la dernière fois qu'il a disparu. Les différents threads de ce camping n'auront pas accès aux objets du camping créé par la pile dans d'autres threads.

Supposons qu'il n'y ait qu'un seul campStove (un seul objet de CampStove, pas d'instanciations séparées). Si, par un effort d'imagination, je partage un objet CampStove, il y a des considérations liées au multithreading. Je ne veux pas allumer mon campStove, disparaître puis réapparaître après qu'un autre campeur l'a éteint - je serais toujours en train de vérifier si mon hot-dog est cuit et il ne le serait jamais. Il faudrait mettre de la synchronisation quelque part... dans la classe CampStove, dans la méthode qui appelle le CampSite, ou dans le CampSite lui-même... mais comme Duncan Jones dit : "c'est une autre affaire".

Notez que même si nous campions dans des instanciations distinctes de non -Les objets CampSite statiques, partageant un campStove, seraient soumis aux mêmes considérations de multithreading.

4voto

SRK Points 100

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

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