2008-11-18 14 views
9

Je me demande comment il serait possible de faire des affirmations sur la synchronisation ou quoi que ce soit pour pouvoir détecter les violations de synchronisation (pendant le test).Comment détecter les violations de synchronisation avec Java

qui serait utilisé par exemple pour le cas que j'aurais une classe qui ne sont pas thread-safe et qui ne va pas être thread-safe. D'une certaine manière, j'aurais une certaine affirmation qui m'informerait (log ou quelque chose) si une ou plusieurs méthodes de celle-ci étaient appelées à partir de plusieurs threads.

Je suis nostalgie de quelque chose de similaire qui pourrait être fait pour le fil d'expédition AWT ce qui suit:

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

Je ne veux quelque chose de plus général. La description du problème n'est pas si claire mais j'espère que quelqu'un a de bonnes approches =)

Répondre

2

Vous êtes à la recherche du Saint Graal, je pense. AFAIK ça n'existe pas, et Java n'est pas un langage qui permet de créer facilement une telle approche. "Java Concurrency in Practice" a une section sur le test des problèmes de threading. Il attire particulièrement l'attention sur la difficulté à faire.

0

Pour l'exemple spécifique que vous donnez, SwingLabs a du code auxiliaire pour détecter les violations de threads d'événements et se bloque. https://swinghelper.dev.java.net/

Un peu en arrière, j'ai travaillé avec les outils de profilage java Jprobe. Un de leurs outils (threadalyzer?) A cherché des violations de synchronisation de fil. En regardant leur page Web, je ne vois pas un outil par ce nom ou tout à fait ce dont je me souviens. Mais vous pourriez vouloir jeter un coup d'oeil. http://www.quest.com/jprobe/performance-home.aspx

2

En cas de problème sur les discussions en Java, il est généralement liée à la détection impasse, plus que la simple surveillance ce que les discussions ont accès à une section synchronisée en même temps. L'extension JMX, ajoutée à JRE depuis la version 1.5, peut vous aider à détecter ces blocages. En fait, nous utilisons JMX dans notre propre logiciel pour détecter automatiquement les blocages d'une trace où ils ont été trouvés. Il s'agit d'un example sur la façon de l'utiliser.

1

En plus de la mention de la superposition de threads de @ Fernando, un autre problème avec plusieurs threads est les modifications simultanées et les problèmes qu'il peut causer. Une chose que fait Java en interne est qu'une classe de collection tient compte du nombre de fois où elle a été mise à jour. Et puis un itérateur vérifie cette valeur sur chaque fichier .next() par rapport à ce qu'il était lorsque l'interateur a été créé pour voir si la collection a été mise à jour pendant que vous itérez. Je pense que ce principe pourrait être utilisé plus généralement.

1

Essayez ConTest ou Covertity

Les deux outils analysent le code pour savoir quelles parties des données peuvent être partagées entre les fils et ils instrumenter le code (ajouter bytecode supplémentaire aux classes compilées) pour vérifier si elle se casse lorsque deux threads tentent de modifier certaines données en même temps. Les deux threads sont ensuite exécutés encore et encore, chaque fois en les commençant avec un décalage de temps légèrement différent pour obtenir de nombreuses combinaisons possibles de modèles d'accès.

Vérifiez également cette question: Unit testing a multithreaded application?

1

Vous pourriez être intéressé par une approche Peter Veentjer blogué à propos, qu'il appelle The Concurrency Detector. Je ne crois pas qu'il l'ait déjà ouvert, mais comme il le décrit, l'idée de base est d'utiliser AOP pour coder le code qui vous intéresse, et d'enregistrer quel thread a touché quel champ. Après cela, il s'agit d'analyser manuellement ou automatiquement les journaux générés.

1

Si vous pouvez identifier les classes non sécurisées, l'analyse statique peut vous indiquer si elles «échappent» à plusieurs threads. Normalement, les programmeurs le font dans leur tête, mais ils sont évidemment enclins à commettre des erreurs à cet égard. Un outil devrait être capable d'utiliser une approche similaire. Cela dit, d'après le cas d'utilisation que vous décrivez, cela ressemble à quelque chose d'aussi simple que de se souvenir d'un fil de discussion et de faire des affirmations à ce sujet 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 remplie même lorsque les assertions sont désactivées, elle n'est donc pas entièrement "gratuite". Je ne voudrais pas non plus encombrer beaucoup de mes classes avec cette passe-partout. La méthode Thread.holdsLock(Object) peut également vous être utile.

2

IntelliJ IDEA a beaucoup de concurrence utile inspections. Par exemple, il vous avertit lorsque vous accédez au même objet à la fois à partir de contextes synchronisés et non synchronisés, lorsque vous synchronisez des objets non finaux, etc.

De même, FindBugs a beaucoup similaire checks.

+0

inspections d'accès concurrentiel utiles ... telles que? :) – bvdb