Maison  >  Article  >  Java  >  Quelles classes en Java sont thread-safe ?

Quelles classes en Java sont thread-safe ?

(*-*)浩
(*-*)浩original
2019-05-21 13:36:398055parcourir

Le cœur de l'écriture de code thread-safe réside dans la gestion des opérations d'accès à l'état, en particulier l'accès à l'état partagé et mutable. Lorsque plusieurs threads accèdent à une variable d'état et qu'un thread effectue une opération d'écriture, un mécanisme de synchronisation doit être utilisé pour coordonner l'accès de ces threads à la variable. Les objets sans état doivent être thread-safe.

Quelles classes en Java sont thread-safe ?

Que se passe-t-il si on ajoute un état à un objet apatride ?

Supposons que l'on ajoute un "hit counter" dans la servlet pour gérer le nombre de requêtes de la manière suivante : ajouter un champ de type long dans la servlet, et ajouter 1 à cette valeur à chaque fois qu'une requête est traité.

public class UnsafeCountingFactorizer implements Servlet {
     private long count = 0;
 
     public long getCount() {
            return count ;
     }
 
     @Override
     public void service(ServletRequest arg0, ServletResponse arg1)
                 throws ServletException, IOException {
            // do something
           count++;
     }
}

Malheureusement, le code ci-dessus n'est pas thread-safe car count++ n'est pas une opération atomique. En fait, il contient trois opérations distinctes : lire la valeur de count, ajouter 1 à la valeur, puis le calcul. le résultat est écrit dans le compte. Si le thread A lit que le compte est 10, le thread B lit immédiatement que le compte est également 10. Le thread A ajoute 1 et écrit dans 11. Le thread B a déjà lu que le compte est 10, donc après avoir ajouté 1 et écrit, il est toujours 11. Un décompte est donc perdu.

En programmation concurrente, ce type de résultat incorrect dû à un timing d'exécution incorrect est une situation très importante. Il a un nom formel : condition de concurrence critique. Le type de condition de concurrence critique le plus courant est l'opération « vérifier d'abord puis exécuter », c'est-à-dire qu'un résultat d'observation potentiellement invalide est utilisé pour déterminer l'opération suivante

L'initialisation paresseuse est une situation courante de. conditions de concurrence :

public class LazyInitRace {
     private SomeObject instance = null;
     public SomeObject getInstance() {
            if(instance == null)
                 instance = new SomeObject();
            return instance ;
     }
}

Contient une condition de concurrence dans LazyInitRace : d'abord, le thread A détermine que l'instance est nulle, puis le thread B détermine que cette instance est également nulle, puis le thread A et le thread B créent respectivement des objets , afin que l'objet subisse deux processus. Une erreur s'est produite lors de l'initialisation.

Pour éviter les conditions statiques, lorsqu'un thread modifie une variable, il est nécessaire d'empêcher les autres threads d'utiliser cette variable d'une manière ou d'une autre, garantissant ainsi que les autres threads ne peuvent lire et modifier l'état qu'avant ou après la modification. l’opération est terminée, plutôt qu’en cours de modification de l’état.
Dans l'exemple UnsafeCountingFactorizer, la raison pour laquelle le thread n'est pas sécurisé est que count++ n'est pas une opération atomique. Nous pouvons utiliser une classe atomique pour garantir que l'opération d'addition est atomique.

Dans cela. De cette façon, la classe est thread-safe :

 public class CountingFactorizer implements Servlet {
     private final AtomicLong count = new AtomicLong(0);
 
    public long getCount() {
          return count .get() ;
   }
 
    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
               throws ServletException, IOException {
          // do something
          count.incrementAndGet();
   }
}

AtomicLong est une classe de variable atomique dans le package java.util.concurrent.atomic. Elle peut implémenter des opérations d'auto-incrémentation atomique, elle est donc thread-safe. sûr.

Recommandations d'apprentissage associées : Tutoriel de base Java

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn