Pergunta

Estou me perguntando que boas maneiras de fazer afirmações sobre sincronização ou algo para que eu pudesse detectar violações de sincronização (durante o teste).

Isso seria usado, por exemplo, para o caso que eu teria uma classe que não é segura para threads e que não será segura por threads. De alguma maneira, eu teria alguma afirmação que me informaria (log ou algo assim) se alguns métodos fossem chamados de vários threads.

Estou desejando algo semelhante que possa ser feito para o AWT Dispatch Thread com o seguinte:

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

Eu só gostaria de algo mais geral. A descrição do problema não é tão clara, mas espero que alguém tenha algumas boas abordagens =)

Foi útil?

Solução

Você está procurando o Santo Graal, eu acho. Afaik, não existe, e o Java não é um idioma que permite que essa abordagem seja facilmente criada.

"Java concorrência na prática" tem uma seção sobre teste para problemas de encadeamento. Chama atenção especial para o quão difícil é fazer.

Outras dicas

Quando surge um problema sobre threads em Java, geralmente está relacionado à detecção de impasse, mais do que apenas monitorar quais threads estão acessando uma seção sincronizada ao mesmo tempo. Jmx A extensão, adicionada ao JRE desde 1,5, pode ajudá -lo a detectar esses impasse. De fato, usamos o JMX dentro de nosso próprio software para detectar automaticamente os deadlocks um rastreamento onde foi encontrado.

Aqui está um exemplo sobre como usá -lo.

Ideia Intellij tem muita simultaneidade útil Inspeções. Por exemplo, ele adverte quando você está acessando o mesmo objeto de contextos sincronizados e não sincronizados, quando está sincronizando em objetos não finais e muito mais.

Da mesma maneira, FindBugs tem muitos semelhantes Verificações.

Assim como a menção de @Fernando ao deadlocking thread, outro problema com vários threads são as modificações simultâneas e os problemas que ele pode causar.

Uma coisa que Java faz internamente é que uma aula de coleção mantém uma contagem de quantas vezes foi atualizada. E então um iterador verifica esse valor em cada .next () contra o que foi quando o interator foi criado para ver se a coleção foi atualizada enquanto você estava iterando. Eu acho que esse princípio poderia ser usado de maneira mais geral.

Tentar Concurso ou Cobertura

Ambas as ferramentas analisam o código para descobrir quais partes dos dados podem ser compartilhadas entre os threads e, em seguida, instrumentam o código (adicione bytecode extra às classes compiladas) para verificar se ele quebra quando dois threads tentam alterar alguns dados ao mesmo tempo . Os dois threads são então atropelados repetidamente, cada vez que os iniciando com um deslocamento de tempo ligeiramente diferente para obter muitas combinações possíveis de padrões de acesso.

Além disso, verifique esta pergunta: Teste de unidade Um aplicativo multithread?

Você pode estar interessado em uma abordagem que Peter Veentjer blogou, sobre o qual ele chama O detector de simultaneidade. Não acredito que ele tenha de código aberto isso ainda, mas, como ele descreve, a idéia básica é usar o Código de AOP para instrumentar que você esteja interessado em perfis e registrar qual tópico tocou em qual campo. Depois disso, é uma questão de análise manual ou automaticamente dos logs gerados.

Se você pode identificar classes inseguras de encadeamento, a análise estática poderá dizer se eles "escaparem" para se tornarem visíveis para vários threads. Normalmente, os programadores fazem isso em suas cabeças, mas obviamente eles são propensos a erros a esse respeito. Uma ferramenta deve poder usar uma abordagem semelhante.

Dito isto, a partir do caso de uso que você descreve, parece algo tão simples quanto lembrar um tópico e fazer afirmações sobre ele pode ser suficiente para suas necessidades.

class Foo {

  private final Thread owner = Thread.currentThread();

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

}

A referência do proprietário ainda é preenchida mesmo quando as afirmações são desativadas, por isso não é totalmente "grátis". Eu também não gostaria de desordenar muitas das minhas aulas com este caldeira.

o Thread.holdslock (objeto) O método também pode ser útil para você.

Para o exemplo específico que você dá, o swinglabs possui algum código auxiliar para detectar violações e pendores de threads de eventos. https://swinghelper.dev.java.net/

Há um tempo, trabalhei com as ferramentas de perfil JProbe Java. Uma de suas ferramentas (ThreadAlyzer?) Procurei violações de sincronização de threads. Olhando para a página da web, não vejo uma ferramenta com esse nome ou exatamente o que me lembro. Mas você pode querer dar uma olhada. http://www.quest.com/jprobe/performance-home.aspx

Você pode usar NetBeans Profiler ou JCONSOLE Para verificar o status dos threads em profundidade

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top