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 ?

98voto

Duncan Points 22780

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

Je conteste ce point. Les arguments transmis à une méthode sont stockés sur une pile, ce qui est un idiome propre à chaque thread.

Si votre paramètre est un objet mutable tel qu'un Date vous devez alors vous assurer que d'autres fils de discussion ne le modifient pas en même temps ailleurs. Mais c'est une autre question qui n'a rien à voir avec la sécurité de votre méthode.

La méthode que vous avez proposée est à l'épreuve des threads. Elle ne conserve aucun état et n'opère que sur ses arguments.

Je vous recommande vivement de lire Concurrence Java en pratique ou un ouvrage similaire consacré à la sécurité des threads en Java. Il s'agit d'un sujet complexe qui ne peut être abordé de manière appropriée par le biais de quelques réponses StackOverflow.

0 votes

@Duncan : Quels autres livres sur le multithreading pouvez-vous recommander ?

0 votes

Il y a un cours sur le multithreading en Java sur educative.io educative.io/collection/5307417243942912/…

6 votes

IMO, lire le livre xyz n'est généralement pas une réponse utile. Pourquoi ne pas aborder la question spécifique de manière plus détaillée au lieu de jeter un livre entier à la figure d'une personne ?

28voto

assylias Points 102015

Comme votre classe ne contient aucune variable membre, votre méthode est sans état (elle n'utilise que des variables locales et l'argument) et est donc sans risque pour les threads.

Le code qui l'appelle peut ne pas être sécurisé, mais c'est une autre discussion. Par exemple, si le code appelant lit une date qui a été écrite par un autre thread, vous devez utiliser une synchronisation appropriée dans le code d'écriture et de lecture de la date.

16voto

rohith Points 304

Compte tenu de la structure de la JVM, les variables locales, les paramètres des méthodes et les valeurs de retour sont intrinsèquement "sûrs pour les threads". Mais les variables d'instance et les variables de classe ne seront sûres pour les threads que si vous concevez votre classe de manière appropriée. plus aquí

15voto

swayamraina Points 431

Je vois beaucoup de réponses, mais aucune n'indique vraiment la raison.

On peut donc envisager les choses de la manière suivante, Chaque fois qu'un thread est créé, il est créé avec sa propre pile (je suppose que la taille de la pile au moment de la création est de ~2MB). Ainsi, toute exécution se produit dans le contexte de cette pile de threads. Toute variable créée vit dans le tas mais sa référence vit dans la pile, à l'exception des variables statiques qui ne vivent pas dans la pile du thread.

Tout appel de fonction que vous faites est en fait poussé sur la pile de threads, qu'il soit statique ou non statique. Puisque la méthode complète a été poussée sur la pile, toute création de variable qui a lieu vit à l'intérieur de la pile (à l'exception des variables statiques) et n'est accessible qu'à un seul thread.

Toutes les méthodes sont donc sûres jusqu'à ce qu'elles modifient l'état d'une variable statique.

8voto

R Kaja Mohideen Points 701

Je recommanderais de créer une copie de cet objet (mutable) dès que la méthode démarre et d'utiliser la copie au lieu du paramètre original.

Quelque chose comme ceci

public static Date getNormalizeDate(Date date) {
    Date input = new Date(date.getTime());
    // ...
}

4 votes

Cela semble intéressant pour la date, mais ne sera pas possible pour les objets personnalisés, surtout s'il s'agit d'un objet personnalisé d'une tierce partie qu'il ne peut pas modifier.

1 votes

Si vous ne pouvez pas cloner dans le cas d'un tiers, vous ne pouvez pas faire grand-chose à part demander à ce tiers de rendre ses instances de classe thread-safe.

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