Question

Je me demande quels sont les bons moyens de faire des affirmations sur la synchronisation ou autre chose afin de pouvoir détecter les violations de synchronisation (lors des tests).

Cela serait utilisé par exemple dans le cas où une classe ne serait pas thread-safe et qu'elle ne le serait pas. D'une manière ou d'une autre, j'aurais une assertion qui m'indiquerait (journal ou quelque chose) si une ou plusieurs méthodes de celle-ci étaient appelées à partir de plusieurs threads.

J'attends quelque chose de similaire qui pourrait être créé pour le thread de répartition AWT avec les éléments suivants:

public static void checkDispatchThread() {
    if(!SwingUtilities.isEventDispatchThread()) {
        throw new RuntimeException("GUI change made outside AWT dispatch thread");
    }
}

Je voudrais seulement quelque chose de plus général. La description du problème n’est pas aussi claire, mais j’espère que les solutions proposées sont bonnes =)

Était-ce utile?

La solution

Vous recherchez le Saint Graal, je pense. Autant que je sache, cela n’existe pas et Java n’est pas un langage qui permet de créer facilement une telle approche.

" Concurrence Java en pratique " a une section sur le test des problèmes de threading. Cela attire particulièrement l'attention sur la difficulté de le faire.

Autres conseils

Lorsqu'un problème survient au niveau des threads en Java, il est généralement lié à la détection d'interblocage, bien au-delà de la simple surveillance des threads qui accèdent simultanément à une section synchronisée. l'extension JMX , ajoutée à JRE depuis la version 1.5, peut aider vous détectez ces impasses. En fait, nous utilisons JMX dans notre propre logiciel pour détecter automatiquement une impasse où une trace a été trouvée.

Voici un exemple sur son utilisation.

IntelliJ IDEA présente de nombreux avantages concurrentiels inspections . Par exemple, il vous avertit lorsque vous accédez au même objet à partir de contextes synchronisés et non synchronisés, lorsque vous synchronisez sur des objets non finaux et autres.

De même, FindBugs a de nombreux vérifie .

Outre les remarques de @ Fernando sur le blocage des threads, les modifications simultanées et les problèmes que cela peut entraîner posent un autre problème avec plusieurs threads.

Une des choses que Java réalise en interne est qu’une classe de collection indique combien de fois elle a été mise à jour. Et puis un itérateur vérifie cette valeur sur chaque .next () par rapport à ce qu'il était lors de la création de l'interator pour voir si la collection a été mise à jour lors de votre itération. Je pense que ce principe pourrait être utilisé plus généralement.

Essayez ConTest ou Covertity

Les deux outils analysent le code pour déterminer quelles parties des données peuvent être partagées entre les threads, puis ils instrumentalisent le code (ajout de bytecode aux classes compilées) pour vérifier s'il se rompt lorsque deux threads tentent de modifier certaines données à le même temps. Les deux threads sont ensuite exécutés maintes et maintes fois, en les démarrant à chaque fois avec un décalage temporel légèrement différent pour obtenir de nombreuses combinaisons possibles de motifs d'accès.

Vérifiez également cette question: Unité testant une application multithread?

Une approche sur laquelle Peter Veentjer a écrit un blog, qu’il appelle nofollow noreferrer "> Le détecteur de concurrence . Je ne crois pas qu'il ait encore ouvert la source, mais comme il l'a décrit, l'idée de base est d'utiliser AOP pour coder le code que vous souhaitez profiler et d'enregistrer le fil qui a touché quel champ. Ensuite, il suffit d'analyser manuellement ou automatiquement les journaux générés.

Si vous pouvez identifier les classes non protégées de threads, une analyse statique pourrait vous indiquer si elles ont déjà "échappé". pour devenir visible à plusieurs threads. Normalement, les programmeurs font cela dans leur tête, mais ils sont évidemment enclins à commettre des erreurs à cet égard. Un outil devrait pouvoir utiliser une approche similaire.

Cela dit, dans le cas d'utilisation que vous décrivez, cela ressemble à quelque chose d'aussi simple que de se souvenir d'un fil et de faire des assertions sur celui-ci pourrait suffire à vos besoins.

class Foo {

  private final Thread owner = Thread.currentThread();

  void x() {
    assert Thread.currentThread() == owner;
    /* Implement method. */
  }

}

La référence du propriétaire est toujours renseignée même lorsque les assertions sont désactivées. Elle n'est donc pas entièrement "gratuite". Je ne voudrais pas non plus encombrer un grand nombre de mes cours avec ce passe-partout.

Le Thread.holdsLock (Object) peut également vous être utile.

Pour l’exemple spécifique que vous donnez, SwingLabs dispose d’un code d’aide permettant de détecter les violations de threads d’événements et les blocages. https://swinghelper.dev.java.net/

Il y a quelque temps, je travaillais avec les outils de profilage java de JProbe. L'un de leurs outils (threadalyzer?) Recherchait les violations de synchronisation des threads. En regardant leur page Web, je ne vois pas un outil portant ce nom ou tout à fait ce dont je me souviens. Mais vous voudrez peut-être jeter un coup d'œil. http://www.quest.com/jprobe/performance-home.aspx

Vous pouvez utiliser profileur Netbeans ou JConsole pour vérifier le statut des threads en profondeur

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top