Vamos dar uma olhada neste código:
Importar java.util.bitset; Thread t1 = novo thread (new Runnable () {public void run () {try {latch.await (); thread.sleep (1000);} catch (exceção ex) {} bs.set (1);}); Thread t2 = new Thread (new runnable () {public void run () {try {latch.await (); thread.sleep (1000);} catch (Exceção e) {} Bs.set (2);}}) ; Start (); :}}A questão é: qual é o resultado dessa saída de código? Que resultados ele pode ser lançado?
Vamos dar uma olhada no que este programa faz:
Em seguida, precisamos construir alguns casos de teste para verificar esses comportamentos. Obviamente, um deles só pode executar este exemplo e, em seguida, observar os resultados e responder às perguntas acima.
A cuidado pode fazer uma coincidência
Felizmente, podemos usar ferramentas. O JCStress é uma ferramenta de teste para resolver esses problemas.
Podemos escrever facilmente nosso caso de teste como um formulário que o JCStress pode reconhecer. De fato, preparou uma variedade de interfaces para nós. Precisamos de um exemplo. Neste exemplo, os dois threads são executados juntos.
Utilizamos um ator2_arbiter1_teest <bitset, interface booleanResult2>. Precisamos encontrar um Java 8 JVM para executá -lo, mas agora isso não é um problema.
Veja a implementação abaixo.
Classe pública Anexampletest implementa ator2_arbiter1_test <bitset, booleanResult2> {@Override public void Actor1 (bitset s, booleanResult2 r) {s.Set (1);} @Override public void2 (Bitset S, booleanResft2) @Override public void2 (Bitset S, booleanRes. );} @Override public void arbiter1 (bitset s, booleanResult2 r) {r.r1 = s.get (1); ;} @Override public boolenrsult2 newResult () {return Now BooleanResult2 ();}}
Agora, ao executar este teste, o controle tentará todos os tipos de truques para obter todas as combinações possíveis de fatores que impulsionam essas ações: paralelo ou não -membro, não há detecção de carga e há muitas vezes em uma linha, muitas vezes, muitas vezes, Muitas vezes, muitas vezes, muitas vezes, portanto, todos os resultados possíveis serão registrados.
Quando você quer saber como está o seu código paralelo, essa é uma maneira melhor de cavar um pensamento oco e pensar em todos os detalhes do que você.
Além disso, para usar a conveniência abrangente trazida pelas restrições da JCStress, precisamos fornecer uma explicação de resultados possíveis.
<nome do teste = "org.openjdk.jcstress.tests.custom.anexampletest"> <limcribui-by> oleg shelajev </contribuído> <descrições se o bitset funcionar bem com a sincronização > MACK> [TRUE, TRUE] </chance> <Expelem> aceitável </spect> <cription> vendo todas as atualizações intactas. /Espere> <cription> T2 substitui o resultado > </socese> <nmatched> <Expeiter> proibido </sten> <cription> Todos os outros casos estão em desinteressado.
Agora, estamos prontos para que este animal comece a rugir.
java -xx:+desblockDiagnósticavMoptions -xx:+whiteboxapi -xx: -resterictContended -jar tests -custot/target/jcstress.jar -t = ".*Anexampletest"
O resultado que obtemos é um relatório elegante.
É claro que podemos não apenas obter os resultados esperados, ou seja, ambos os threads definiram suas posições, mas também encontram uma condição competitiva, e um thread cobrirá o resultado de outro thread.
Mesmo se você vir uma coisa dessas, deve ter a mentalidade calma de "o povo da montanha tem seus próprios truques", não é?
A propósito, se você está pensando em como modificar esse código, a resposta é ler cuidadosamente a classe Bitset em Javadoc e perceber que não é uma segurança de thread e requer sincronização externa. Isso pode ser facilmente alcançado aumentando os valores de configuração dos blocos síncronos.
sincronizado (bs) {bs.set (1);}