Domanda

Mi chiedo quali buoni modi ci sarebbero per fare affermazioni sulla sincronizzazione o qualcosa del genere in modo da poter rilevare violazioni della sincronizzazione (durante il test).

Sarebbe usato ad esempio nel caso in cui avessi una classe che non è thread-safe e che non sarà thread-safe. In qualche modo avrei qualche affermazione che mi informerebbe (log o qualcosa del genere) se alcuni metodi fossero stati chiamati da più thread.

Sto desiderando qualcosa di simile che potrebbe essere fatto per il thread di invio AWT con il seguente:

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

Vorrei solo qualcosa di più generale. La descrizione del problema non è così chiara ma spero che qualcuno abbia dei buoni approcci =)

È stato utile?

Soluzione

Stai cercando il Santo Graal, penso. AFAIK non esiste e Java non è un linguaggio che consente di creare facilmente un simile approccio.

" Concorrenza Java in pratica " ha una sezione sui test per problemi di threading. Richiama un'attenzione speciale su quanto sia difficile da fare.

Altri suggerimenti

Quando si verifica un problema sui thread in Java, di solito è correlato al rilevamento dei deadlock, oltre al semplice monitoraggio dei thread che accedono contemporaneamente a una sezione sincronizzata. estensione JMX , aggiunta a JRE dall'1.5, può aiutare rilevi quei deadlock. Infatti, utilizziamo JMX all'interno del nostro software per rilevare automaticamente deadlock una traccia in cui è stato trovato.

Ecco un esempio su come usarlo.

IntelliJ IDEA ha molta concorrenza utile ispezioni . Ad esempio, ti avvisa quando accedi allo stesso oggetto da contesti sia sincronizzati che non sincronizzati, quando esegui la sincronizzazione su oggetti non finali e altro.

Allo stesso modo, FindBugs ha molti simili assegni .

Oltre alla menzione di @ Fernando del deadlock dei thread, un altro problema con più thread sono le modifiche simultanee e i problemi che può causare.

Una cosa che Java fa internamente è che una classe di raccolta tiene conto di quante volte è stata aggiornata. E poi un iteratore verifica quel valore su ogni .next () rispetto a quello che era quando l'interatore è stato creato per vedere se la raccolta è stata aggiornata mentre si stava ripetendo. Penso che questo principio possa essere usato più in generale.

Prova ConTest o Covertity

Entrambi gli strumenti analizzano il codice per capire quali parti dei dati potrebbero essere condivise tra i thread e quindi strumentano il codice (aggiungi un bytecode extra alle classi compilate) per verificare se si interrompe quando due thread tentano di modificare alcuni dati in lo stesso tempo. I due thread vengono quindi ripetuti più e più volte, avviandoli ogni volta con un offset del tempo leggermente diverso per ottenere molte possibili combinazioni di schemi di accesso.

Inoltre, controlla questa domanda: Unità che sta testando un'applicazione multithread?

Potresti essere interessato ad un approccio su cui Peter Veentjer ha scritto un blog, che chiama Il rilevatore di concorrenza . Non credo che l'abbia ancora aperto, ma mentre lo descrive l'idea di base è usare AOP per codificare lo strumento che ti interessa profilare e registrare quale thread ha toccato quale campo. Dopodiché si tratta di analizzare manualmente o automaticamente i registri generati.

Se riesci a identificare le classi non sicure del thread, l'analisi statica potrebbe essere in grado di dirti se mai "scappano". per diventare visibile a più thread. Normalmente, i programmatori lo fanno nelle loro teste, ma ovviamente sono inclini a errori in questo senso. Uno strumento dovrebbe essere in grado di utilizzare un approccio simile.

Detto questo, dal caso d'uso che descrivi, sembra qualcosa di semplice come ricordare un thread e fare affermazioni su di esso potrebbe essere sufficiente per le tue esigenze.

class Foo {

  private final Thread owner = Thread.currentThread();

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

}

Il riferimento del proprietario è ancora popolato anche quando le asserzioni sono disabilitate, quindi non è del tutto "gratuito". Inoltre, non vorrei ingombrare molte delle mie lezioni con questa piastra di cottura.

The Thread.holdsLock (Object) può anche esserti utile.

Per l'esempio specifico fornito, SwingLabs ha un codice di supporto per rilevare violazioni e blocchi del thread di eventi. https://swinghelper.dev.java.net/

Qualche tempo fa, ho lavorato con gli strumenti di profilazione java di JProbe. Uno dei loro strumenti (threadalyzer?) Ha cercato violazioni della sincronizzazione dei thread. Guardando la loro pagina web, non vedo uno strumento con quel nome o quello che ricordo. Ma potresti voler dare un'occhiata. http://www.quest.com/jprobe/performance-home.aspx

Puoi utilizzare Netbeans profiler o JConsole per verificare lo stato dei thread in profondità

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top