Echemos un vistazo a este código:
Import java.util.bitset; Thread t1 = new Thread (new runnable () {public void run () {try {latch.await (); thread.sleep (1000);} capt (excepción ex) {} bs.set (1);}); Thread t2 = new Thread (new Runnable () {public void run () {try {latch.await (); thread.sleep (1000);} capt (excepción e) {} bs.set (2);}}) ; Start () T2.Start (); :}}La pregunta es, ¿cuál es el resultado de esta salida de código? ¿Qué resultados puede generar?
Echemos un vistazo a lo que hace este programa:
A continuación, necesitamos construir algunos casos de prueba para verificar estos comportamientos. Obviamente, uno de ellos solo puede ejecutar este ejemplo, y luego observar los resultados y responder las preguntas anteriores.
El cuidado puede hacer una coincidencia
Afortunadamente, podemos usar herramientas. JCSress es una herramienta de prueba para resolver tales problemas.
Podemos escribir fácilmente nuestro caso de prueba como un formulario que JCSTRESS puede reconocer. De hecho, ha preparado una variedad de interfaces para nosotros. Necesitamos un ejemplo.
Utilizamos una interfaz actor2_arbiter1_teest <bitset, booleanResult2> proporcionará algunos bloques de método y un método de conversión para nuestros dos hilos. Necesitamos encontrar un Java 8 JVM para ejecutarlo, pero ahora esto no es un problema.
Mira la implementación a continuación.
La clase pública anexaMpletest implementa actor2_arbiter1_test <bitset, booleanResult2> {@Override public void actor1 (bitset S, booleanResult2 r) {s.set (1);} @Override public void actor2 (bitset S, booleanResult2 r) {s.set (2 (2) );} @Override public void Arbiter1 (bitset S, booleanResult2 r) {r.r1 = s.get (1); ;} @Override public boolenrsult2 newResult () {return new booleanResult2 ();}}
Ahora, al ejecutar esta prueba, el control intentará todo tipo de trucos para obtener todas las combinaciones posibles de factores que impulsan estas acciones: paralelo o no femenera, no hay detección de carga, y hay muchas veces en una línea, muchas veces, Muchas veces, muchas veces, muchas veces, por lo tanto, se registrarán todos los resultados posibles.
Cuando desea saber cómo está su código paralelo, esta es una mejor manera de cavar un pensamiento hueco y pensar en todos los detalles que usted.
Además, para utilizar la comodidad integral traída por las restricciones JCSress, necesitamos proporcionarle una explicación de los posibles resultados.
<test name = "org.openjdk.jcstress.tests.custom.anexaMpletest"> <contribuyó-by> oleg shelajev </abded-by> <descripciones si bitset funciona bien con sincronización. > Match> [true, true] </sport> <seppect> aceptable </spe> <scuidt> viendo todas las actualizaciones intactas. /Esperar> <Scuion> T2 sobrescribe el resultado T1. > </Case> <nmatched> <pese> Prohibido </exten> <Scoltion> Todos los demás casos están en Onlenexpected.
Ahora, estamos listos para que esta bestia comience a rugir.
java -xx:+desorglockdiagnticVMoptions -xx:+whiteboxapi -xx: -resterictcontended -jar tests -custot/target/jcstress.jar -t = ".*anexaMpletest"
El resultado que obtenemos es un informe elegante.
Está claro que no solo podemos obtener los resultados esperados, es decir, ambos hilos han establecido sus posiciones, sino que también encuentran una condición competitiva, y un hilo cubrirá el resultado de otro hilo.
Incluso si ves tal cosa, debes tener la mentalidad tranquila de "la gente de la montaña tiene sus propios trucos", ¿no?
Por cierto, si está pensando en cómo modificar este código, la respuesta es leer cuidadosamente la clase Bitset en Javadoc y darse cuenta de que no es una seguridad de hilo y requiere una sincronización externa. Esto se puede lograr fácilmente aumentando los valores de configuración de los bloques sincrónicos.
sincronizado (bs) {bs.set (1);}