Concours Servlet

Bonjour à tous!

Nous lançons le septième volet du cours Java Developer . En plus d'un an d'existence de ce cours, il a été affiné, affiné, un nouveau a été ajouté qui dépassait ce temps. Le même flux diffère du reste en ce que nous avons introduit un nouveau système d'étapes, divisant le cours en trois parties et augmentant légèrement sa durée totale. Alors maintenant, il ne sera pas nécessaire d'être épuisé pendant cinq mois consécutifs pour obtenir un certificat, mais de choisir calmement des périodes de deux mois et de suivre une formation. Mais ce sont les paroles, revenons à notre tradition concernant les différents utilitaires précédant le lancement du cours.

Allons-y.

1. Présentation


Le conteneur de servlet Java (ou serveur Web) est multithread: plusieurs requêtes vers le même servlet peuvent être exécutées simultanément. Par conséquent, lors de l'écriture d'un servlet, vous devez tenir compte de la concurrence.

Comme nous l'avons dit précédemment, une et une seule instance de servlet est créée et pour chaque nouvelle demande, le conteneur de servlet crée un nouveau thread pour exécuter les méthodes doGet () ou doPost () de la servlet.

Par défaut, les servlets ne sont pas thread-safe, le programmeur doit s'en occuper lui-même. Dans ce chapitre, nous discuterons de la compétition des servlets. Il s'agit d'un concept très important, alors concentrez-vous.

2. Aperçu des discussions




Un thread est un processus léger qui possède sa propre pile d'appels et accède aux données ouvertes d'autres threads du même processus (segment partagé). Chaque thread a son propre cache.

Lorsque nous disons qu'un programme est multithread, nous voulons dire que la même instance d'un objet génère plusieurs threads et traite un seul élément de code. Cela signifie que plusieurs flux de contrôle consécutifs passent par le même bloc de mémoire. Ainsi, plusieurs threads exécutent une instance d'un programme et, par conséquent, partagent des variables d'instance et peuvent essayer de lire et d'écrire ces variables partagées.

Regardons un exemple Java simple.

public class Counter { int counter=10; public void doSomething() { System.out.println(“Inital Counter = ” + counter); counter ++; System.out.println(“Post Increment Counter = ” + counter); } } 

Maintenant, nous créons deux threads Thread1 et Thread2 pour faire doSomething() . En conséquence, il est possible que:

  1. Thread1 lit une valeur de compteur de 10
  2. Affiche le compteur initial = 10 et va augmenter
  3. Avant Thread1 incrémente le compteur, Thread2 incrémente également le compteur, en changeant le compteur à 11
  4. Par conséquent, Thread1 a une valeur de compteur de 10, qui est déjà obsolète

Ce scénario est possible dans un environnement multithread, tel que les servlets, car les variables d'instance sont partagées par tous les threads s'exécutant dans la même instance.

3. Écriture de servlets thread-safe


J'espère que dans cette section, vous comprendrez les problèmes que j'essaie de souligner. En cas de doute, relisez le point 2.

Il y a certains points que nous devons considérer lors de l'écriture des servlets.

  1. Service() , doGet() , doPost() ou, plus généralement, les méthodes doXXX() ne doivent pas mettre à jour ou modifier les variables d'instance, car les variables d'instance sont partagées par tous les threads de la même instance.
  2. S'il est nécessaire de modifier la variable d'instance, faites-le dans un bloc synchronisé.
  3. Les deux règles ci-dessus s'appliquent également aux variables statiques car elles sont également courantes.
  4. Les variables locales sont toujours thread-safe.
  5. Les objets de demande et de réponse sont sûrs pour l'utilisation car une nouvelle instance est créée pour chaque demande dans votre servlet et, par conséquent, pour chaque thread s'exécutant dans votre servlet.

Voici deux approches pour garantir la sécurité des threads:

a) Synchronisez le bloc dans lequel vous modifiez l'instance ou les variables statiques (voir l'extrait de code ci-dessous).

Nous vous recommandons de synchroniser le bloc dans lequel votre code modifie les variables d'instance au lieu de synchroniser la méthode complète afin d'améliorer les performances.

Notez que nous devons verrouiller l'instance de servlet car nous devons sécuriser le thread d'instance de servlet spécifique.

 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ThreadSafeServlet extends HttpServlet { @override public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException int counter; { synchronized (this) { //code in this block is thread-safe so update the instance variable } //other processing; } 

b) Modèle à un seul thread - implémentez l'interface SingleThreadModel pour rendre le thread simple, ce qui signifie qu'un seul thread exécutera la méthode service () ou doXXX () à la fois. Un servlet à thread unique est plus lent sous charge car les nouvelles requêtes doivent attendre qu'une instance gratuite soit traitée

 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ThreadSafeServlet extends HttpServlet implements SingleThreadModel { int counter; // no need to synchronize as implemented SingleThreadModel @override public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } 

L'utilisation de SingleThreadModel est obsolète car il est recommandé d'utiliser des blocs synchronisés.

4. Conclusion


Nous devons être très prudents lors de l'écriture des servlets, car "par défaut, les servlets ne sont pas thread-safe"

  1. Si votre servlet n'a pas de variable statique ou de membre, ne vous inquiétez pas et votre servlet est thread-safe
  2. Si votre servlet lit simplement la variable d'instance, votre servlet est thread-safe.
  3. Si vous devez modifier une instance ou des variables statiques, mettez-les à jour dans un bloc synchronisé, en gardant l'instance verrouillée

Si vous suivez les règles ci-dessus et la prochaine fois que quelqu'un vous demandera: "Le thread de servlet est-il sûr?" - Répondez en toute confiance: "Par défaut, ils ne le sont pas, mais" Mes servlets "sont thread-safe."

LA FIN

Comme toujours, nous attendons vos questions, suggestions, etc. ici ou vous pouvez demander à Sergey Petrelevich lors de la leçon ouverte sur le multithreading.

Source: https://habr.com/ru/post/fr414759/


All Articles