El análisis más completo del uso de Java Múltiple. Si no ha realizado una investigación en profundidad sobre el mecanismo de lectura múltiple de Java, entonces este artículo puede ayudarlo a comprender más a fondo los principios y los métodos de uso de Java Multhrithreading.
1. Crea un hilo
Hay dos formas de crear hilos en Java: usando la clase de subprocesos y usando la interfaz Runnable. Al usar la interfaz Runnable, debe crear una instancia de subproceso. Por lo tanto, ya sea que esté estableciendo un hilo a través de la clase de hilo o la interfaz ejecutable, debe establecer una instancia de la clase de subproceso o su subclase. Constructor de hilo:
Método 1: heredar la clase de subprocesos y sobrescribir el método Ejecutar
public class ThreadDemo1 {public static void main (string [] args) {demo d = new Demo (); D.Start (); for (int i = 0; i <60; i ++) {system.out.println (thread.currentThread (). getName ()+i); }}} La demostración de clase extiende el hilo {public void run () {for (int i = 0; i <60; i ++) {System.out.println (Thread.CurrentThread (). GetName ()+I); }}}Método 2:
public class ThreadDemo2 {public static void main (string [] args) {demo2 d = new Demo2 (); Hilo t = nuevo hilo (d); t.Start (); for (int x = 0; x <60; x ++) {system.out.println (thread.currentThread (). getName ()+x); }}} class Demo2 implementa Runnable {public void run () {for (int x = 0; x <60; x ++) {system.out.println (thread.currentThread (). getName ()+x); }}}2. El ciclo de vida de los hilos
Al igual que las personas tienen nacimiento, vejez, enfermedad y muerte, los hilos también tienen que pasar por cuatro estados diferentes: comenzar (esperar), correr, suspender y parar. Los cuatro estados pueden ser controlados por métodos en la clase de subprocesos. El siguiente es un método relacionado con estos cuatro estados en la clase de hilo.
// Iniciar hilo
Publicvoid Start ();
publicvoid run ();
// suspender y despertar hilos
currículum de publicvoid (); // no se recomienda usar
PublicVoid Suspend (); // no se recomienda usar
PublicStaticvoid Sleep (Long Millis);
PublicStaticvoid Sleep (Long Millis, Int Nanos);
// Terminar el hilo
Publicvoid stop (); // no se recomienda usar
Interrupción de PublicVoid ();
// Obtener el estado del hilo
PublicBoolean isalive ();
PublicBoolean isInterrupted ();
PublicStaticBoolean interrumpió ();
// Método de unión
publicvoid unir () lanza interruptedException;
Después de establecer el hilo, no ejecuta el código en el método de ejecución inmediatamente, pero está en un estado de espera. Cuando el hilo está en un estado de espera, puede usar el método de clase de subprocesos para establecer varias propiedades del hilo, como la prioridad del hilo (setpriority), el nombre del hilo (setname) y el tipo de subproceso (setdaemon), etc.
Después de llamar al método de inicio, el hilo comienza a ejecutar el código en el método Ejecutar. El hilo ingresa al estado en ejecución. Puede usar el método isalive de la clase de subprocesos para determinar si el hilo está en estado en ejecución. Cuando el hilo está en el estado en ejecución, Isalive devuelve verdadero. Cuando Isalive regresa falso, el hilo puede estar en el estado de espera o en el estado de parada. El siguiente código demuestra el cambio entre los tres estados de creación, ejecución y detención de los subprocesos, y genera el valor de retorno isalive correspondiente.
Una vez que el hilo comienza a ejecutar el método de ejecución, el hilo no saldrá hasta que se ejecute el método de ejecución. Sin embargo, durante la ejecución de un hilo, el hilo puede detener temporalmente por dos métodos. Estos dos métodos son suspender y dormir. Después de suspender el hilo con suspensión, el hilo se puede despertar a través del método de currículum. Después de usar el sueño para dormir, el hilo solo se puede poner en el estado listo después de la hora establecida (después de que el hilo duerme, el hilo no puede ejecutarse de inmediato, pero solo entra en el estado listo y espera a que el sistema programen).
Hay dos cosas a tener en cuenta al usar el método de sueño:
1. El método de sueño tiene dos formularios de sobrecarga. Uno de los formularios de sobrecarga no solo puede establecerse en milisegundos, sino también nanosegundos (1,000,000 de nanosegundos es igual a 1 milisegundo). Sin embargo, las máquinas virtuales Java en la mayoría de las plataformas del sistema operativo no pueden ser precisas para los nanosegundos, por lo que si los nanosegundos están configurados para dormir, la máquina virtual Java tomará los milisegundos más cercanos a este valor.
2. Al usar el método de sueño, debe usar lanzamientos o intentar {...} Catch {...}. Debido a que el método de ejecución no puede usar lanzamientos, solo puede usar Try {...} Catch {...}. Cuando el hilo está durmiendo, el sueño lanzará una excepción de InterruptedException al interrumpir el hilo utilizando el método de interrupción. El método de sueño se define de la siguiente manera:
PublicStaticvoid Sleep (Long Millis) lanza interruptedException
PublicStaticvoid Sleep (Long Millis, Int Nanos) lanza interrupción de Excepción
Hay tres formas de terminar el hilo.
1. Use el indicador de salida para hacer la salida del hilo normalmente, es decir, el hilo termina cuando se completa el método de ejecución.
2. Use el método de parada para terminar con fuerza el hilo (este método no se recomienda porque la parada es la misma que la suspensión y el reanudación, y también puede tener resultados impredecibles).
3. Use el método de interrupción para interrumpir el hilo.
1. Use el indicador de salida para terminar el hilo
Cuando se ejecuta el método de ejecución, el hilo saldrá. Pero a veces el método de ejecución nunca termina. Por ejemplo, el uso de hilos para escuchar las solicitudes de los clientes en programas de servidor u otras tareas que requieren procesamiento de bucle. En este caso, estas tareas generalmente se colocan en un bucle, como el bucle mientras. Si desea que el bucle se ejecute para siempre, puede usar mientras (verdadero) {...} para manejarlo. Sin embargo, si desea realizar la salida del bucle While en una determinada condición, la forma más directa es establecer un indicador de tipo booleano y controlar si el bucle While sale configurando este indicador en verdadero o falso. Aquí hay un ejemplo de terminar un hilo usando el indicador de salida.
La función del método de unión es convertir el hilo de ejecución asíncrono en ejecución síncrona. Es decir, cuando se llama el método de inicio de la instancia de subproceso, el método volverá inmediatamente. Si se debe usar un valor calculado por este subproceso después de que se llame al método de inicio, se debe usar el método de unión. Si no usa el método de unión, no se puede garantizar que cuando se ejecuta una declaración detrás del método de inicio, se ejecutará el hilo. Después de usar el método de unión, el programa no se ejecutará hasta que salga el hilo. El siguiente código demuestra el uso de unión.
3. Problemas de seguridad multiproceso
Causa del problema: cuando múltiples declaraciones funcionan en el mismo hilo para compartir datos, un hilo solo ejecuta parte de múltiples declaraciones, pero aún no ha terminado de ejecutarlo, y otro hilo participa en la ejecución, lo que resulta en un error al compartir datos.
Solución: para múltiples declaraciones que comparten datos con múltiples operaciones, solo se puede ejecutar un hilo. Durante el proceso de ejecución, otros hilos no se ejecutan.
Sincronizar bloques de código:
public class ThreadDemo3 {public static void main (string [] args) {ticket t = new ticket (); Hilo t1 = nuevo hilo (t, "ventana uno"); Hilo t2 = nuevo hilo (t, "ventana dos"); Hilo t3 = nuevo hilo (t, "ventana tres"); Hilo t4 = nuevo hilo (t, "ventana cuatro"); t1.start (); t2.start (); t3.start (); t4.Start (); }} El boleto de clase implementa runnable {private int ticket = 400; public void run () {while (true) {sincronizado (nuevo objeto ()) {try {thread.sleep (1); } Catch (InterruptedException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } if (ticket <= 0) ruptura; System.out.println (Thread.CurrentThread (). GetName ()+"--- vender"+ticket--); }}}}Funciones sincrónicas
public class ThreadDemo3 {public static void main (string [] args) {ticket t = new ticket (); Hilo t1 = nuevo hilo (t, "ventana uno"); Hilo t2 = nuevo hilo (t, "ventana dos"); Hilo t3 = nuevo hilo (t, "ventana tres"); Hilo t4 = nuevo hilo (t, "ventana cuatro"); t1.start (); t2.start (); t3.start (); t4.Start (); }} El boleto de clase implementa runnable {private int ticket = 4000; Public sincronizado void saleticket () {if (ticket> 0) system.out.println (thread.currentThread (). getName ()+"vendido"+ticket--); } public void run () {while (true) {saleticket (); }}}El bloqueo de la función síncrona es este bloqueo de función de sincronización estática es clase
Comunicación entre hilos
public class ThreadDemo3 {public static void main (string [] args) {class Person {public String Name; género de cadena privada; Public void set (name de cadena, género de cadena) {this.name = name; this.gender = género; } public void get () {System.out.println (this.name+"...."+this.gender); }} persona final p = nueva persona (); new Thread (new runnable () {public void run () {int x = 0; while (true) {if (x == 0) {p.set ("zhang san", "masculino");} else {p.set ("lili", "nv");} x = (x+1)%2;}}). new Thread (new Runnable () {public void run () {while (true) {p.get ();}}}). start (); }}/ *Zhang san .... macho zhang san .... macho lili .... nvlili .... macho zhang san .... nvlili .... macho */Modificar el código anterior
public class ThreadDemo3 {public static void main (string [] args) {class Person {public String Name; género de cadena privada; Public void set (name de cadena, género de cadena) {this.name = name; this.gender = género; } public void get () {System.out.println (this.name+"...."+this.gender); }} persona final p = nueva persona (); new Thread (new runnable () {public void run () {int x = 0; while (true) {sincronizado (p) {if (x == 0) {p.set ("zhang san", "masculino");} else {p.set ("lili", "nv");} x = (x+1)%2;}}}}}}}). new Thread (new runnable () {public void run () {while (true) {sincronizado (p) {p.get ();}}}}}). start (); }} /* lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv zhang san San .... macho zhang san .... macho */Esperando el mecanismo de despertar
/**Mecanismo de activación de hilo de espera*Espera y despertar debe ser el mismo bloqueo*/public class ThreadDemo3 {private static boolean flags = false; public static void main (string [] args) {persona de clase {nombre de cadena public; género de cadena privada; Public void set (name de cadena, género de cadena) {this.name = name; this.gender = género; } public void get () {System.out.println (this.name+"...."+this.gender); }} persona final p = nueva persona (); new Thread (new runnable () {public void run () {int x = 0; while (true) {sincronizado (p) {if (flags) try {p.wait ();} catch (interruptedException e) {// toDO Generated Catch Bloque E.PrintStackAtRace ();}; if (x == 0) {P.Set ("San", "San", "San", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", "," San "," SAN "; } else {p.set ("lili", "nv"); new Thread(new Runnable(){ public void run(){ while(true){ synchronized (p) { if(!flags) try { p.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }; p.get(); flags =false; p.notifyAll(); } } } } }).comenzar(); }}Mecanismo de producción y consumo uno
clase pública ThreadDemo4 {Flaros de booleanos estáticos privados = falso; public static void main (string [] args) {gaseos de clase {nombre de cadena privada; privado int num; Public sincronizado void product (nombre de cadena) {if (flags) try {wait (); } Catch (InterruptedException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } this.name = nombre+"número:"+num ++; System.out.println ("producido ......"+this.name); banderas = verdadero; notifyall (); } public sincronizado sincronizado consumo () {if (! flags) try {wait (); } Catch (InterruptedException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } System.out.println ("consumido *****"+nombre); banderas = falso; notifyall (); }} bienes finales g = new Goods (); new Thread (new runnable () {public void run () {while (true) {g.produce ("producto");}}}). start (); new Thread (new Runnable () {public void run () {while (true) {g.consume ();}}}). start (); }}Mecanismo de producción y consumo 2
clase pública ThreadDemo4 {Flaros de booleanos estáticos privados = falso; public static void main (string [] args) {gaseos de clase {nombre de cadena privada; privado int num; Public sincronizado void product (nombre de cadena) {while (flags) try {wait (); } Catch (InterruptedException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } this.name = nombre+"número:"+num ++; System.out.println (thread.currentThread (). GetName ()+"producido ..."+this.name); banderas = verdadero; notifyall (); } public sincronizado void consumen () {while (! flags) intente {wait (); } Catch (InterruptedException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } System.out.println (thread.currentThread (). GetName ()+"consumido *******"+nombre); banderas = falso; notifyall (); }} bienes finales g = new Goods (); new Thread(new Runnable(){ public void run(){ while(true){ g.produce("product"); } } },"Produce("product"); } } },"Produce("product"); } } },"Produce("product"); } } },"Produce("product"); } } },"Produce("product"); } } }, "Consumer No. 1"). Start (); Consumido ******* Número de productos: 48050 PRODUCER No. 1 Producido ... Número de productos básicos: 48051Consumer No. 2 Consumido **** Número de productos: 48051 Productor No. 2 producido ... Número de productos básicos: 480522Consumer No. 2 consumido *** *** Número de productos básicos: 48052producter n. ° 1 ha sido producido. 48053Consumer No. 1 se ha consumido ******* Número de productos básicos: 48053 PRODUCER No. 1 ha sido producido ... Número de productos básicos: 48054Consumer No. 2 ha sido consumido ******* Número de productos: 48054 4PRODUCER No. 2 se ha producido ... Número de productos básicos: 4805555555555555555555555 años ha sido consumido ***************. 48055*/Lo anterior es la compilación de información multiproceso de Java. Continuaremos agregando conocimiento relevante en el futuro. ¡Gracias por su apoyo para este sitio web!