Este artículo demuestra principalmente el escenario de procesamiento concurrente multiproceso de programación Java a través de un ejemplo de usuarios bancarios que retiran dinero, de la siguiente manera.
Comience con un ejemplo: Implemente el código de ejemplo para un escenario de retiro de cuenta bancaria.
La primera clase: Account.java
Categoría de cuenta:
paquete cn.edu.byr.test; cuenta de clase pública {private string cuenta cuenta; doble getbalance () {return this.balance;} public void setBalance (doble balance) {this.balance = balance;} public boolean iguales (object obj) {if (this == OBJ) return true; if (obj! = null && obj.getClass () == cuenta.class) {cuento = (cuenta) obj; regreso; regreso; Target.getAccountno (). Equals (Accountno);} return false;}} La segunda clase: Drawthread.java
Clase de hilo de retiro de dinero:
paquete cn.edu.byr.test; public class DrawThread extiende el hilo {cuenta privada de cuenta; private double Drawamount; public DrawThread (name de cadena, cuenta de cuenta, doble dibujo drawamount) {super (name); this.account = cuenta; this.drawamount = drawamount;} public void run () drawamount) {System.out.println (getName () + "Obtenga dinero con éxito, escupe los bankNotes:" + drawamount); // try {// hilt.sleep (1); //} // Catch (InterruptedException e) {// E.PrintStackTrace (); //} Account.SetBalance (Account.getBalance () - Drawamount); System.out.println ("/t El saldo es:" + cuenta.getBalance ());} else System.out.println (getName () + "Get Retire Money fallado, el saldo es insuficiente!"); //}} public static void main (string [] args) {cuenta acct = nueva cuenta ("123456", 1000); nuevo void estático estático (string [] args) {cuenta de cuenta = nueva cuenta ("123456", 1000); nuevo void estático estático (string [] args) {cuenta de cuenta = nueva cuenta ("123456", 1000); nuevo void estático estático (string [] args) {cuenta de cuenta = nueva cuenta ("123456", 1000); nuevo void estático estático (String [] args) {cuenta de cuenta = nueva cuenta ("123456", 1000); nuevo; Drawthread ("A", Acct, 800) .Start (); New Drawthread ("B", Acct, 800) .Start ();}} La parte comentada en el código anterior: (1) Bloque de código de sincronización sincronizado (2) Hibernación de subprocesos. Si (1) y (2), hay muchas posibilidades para el resultado de la ejecución, una de las posibilidades (la probabilidad es pequeña), que se ajusta a la lógica normal:
B retira con éxito el dinero, escupe el dinero: 800.0
El equilibrio es: 200.0
¡Un retiro fallido y el saldo fue insuficiente!
Debe ser que B primero encuentre el recurso de retiro de dinero y modifique el saldo correctamente antes de que A comience a juzgar el saldo del usuario; Esta probabilidad es muy pequeña, y la mayoría de las operaciones serán similares a las siguientes situaciones:
A retira el dinero con éxito y escupe el dinero: 800.0
B retira con éxito el dinero, escupe el dinero: 800.0
El saldo es: -600.0
El equilibrio es: 200.0
Esto es obviamente ilógico. A partir de los resultados en ejecución, podemos adivinar que A primero toma el recurso y retira la cantidad, pero antes de modificar el saldo, B es incautado por B; Dado que el saldo no se ha modificado, B ve que el saldo aún es 800, y B todavía retira la cantidad; Un primero ejecuta el saldo de modificación, pero no lo imprime, B arrebata el recurso; B modifica el saldo e imprime el saldo, que es -600; A imprime el saldo, que es 200;
Si (2) duerme el hilo, debe ser una condición de error, porque A o B liberará los recursos de la CPU debido al sueño después de obtener la cantidad, y el JVM llamará a otros procesos en el estado listo. Lo segundo es retirar dinero y juzgar el saldo debe estar mal.
Si (1) se agrega un bloque de código sincronizado sincronizado, la cuenta está bloqueada en el cuerpo del método de ejecución de subprocesos; entonces se garantizará que la lógica de ejecución sea normal cada vez:
A retira el dinero con éxito y escupe el dinero: 800.0
El equilibrio es: 200.0
B no pudo retirar dinero, y el saldo era insuficiente!
Puedes imaginar el proceso de ejecución:
Primero se adelanta al recurso y bloquea la clase de cuenta inicialmente en el cuerpo del método Ejecutar; Luego comienza a ejecutar el bloque de código sincrónico; Si se ejecuta a un determinado enlace en el medio, el recurso de la CPU está previsto por B; B comienza a ejecutar y bloquea la clase de cuenta al principio. Sin embargo, al agregar un bloqueo, encontrará que la cuenta ha sido ocupada por A, y se ajustará a un estado de bloqueo y esperará a que A lance el recurso; Después de que A haya ejecutado el bloque de código síncrono, se lanzará el bloqueo de la cuenta y B continuará ejecutándose; El saldo visto durante la ejecución B está garantizado para ser modificado por A y se ejecutará normalmente de acuerdo con la lógica correcta.
Resumir
Lo anterior es todo el contenido de este artículo sobre el análisis de instancias de procesamiento concurrentes multiproceso de programación Java, y espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!