Resumen de aprendizaje de Java: 26

Hilos y procesos

Un proceso es un proceso de ejecución dinámico de un programa. Ha pasado por un proceso completo desde la carga y ejecución del código hasta la finalización de la ejecución. Este proceso también es el proceso del proceso mismo desde la generación, el desarrollo hasta la desaparición final.
Los subprocesos son unidades de ejecución más pequeñas que los procesos. Los subprocesos se dividen aún más en función de los procesos. Un proceso puede contener múltiples subprocesos que se ejecutan simultáneamente.La diferencia entre proceso e hilo

Nota: Todos los hilos deben estar unidos al proceso para existir. Una vez que el proceso desaparece, el hilo también desaparecerá. Java es uno de los pocos lenguajes de desarrollo que admite subprocesos múltiples.

Implementación multiproceso

En Java, si desea implementar un programa de subprocesos múltiples, debe confiar en el cuerpo principal de un subproceso (que representa la clase principal de un subproceso). Pero el cuerpo de la clase principal de este hilo también debe tener algunos requisitos especiales cuando se define, es decir, esta clase necesita heredar la clase Thread o implementar la interfaz Runnable (invocable) para completar la definición.

Heredar clase de subproceso

java.lang.Thread es una clase responsable de las operaciones de subproceso, cualquier clase solo necesita heredar la clase de subproceso para convertirse en la clase principal de un subproceso. El formato de definición de la clase principal de hilo es el siguiente:

class 类名称 extends Thread{	//继承Thread类
	属性...;					//类中定义属性
	方法...;					//类中定义方法
	public void run(){			//覆写Thread类中的run()方法,此方法是线程的主体
		线程主体方法;
	}
}

Ejemplo: iniciar múltiples hilos

package Project.Study.Multithreading;
import java.lang.Thread;

class MyThread extends Thread{		//这就是一个多线程的操作类
    private String name;			//定义类中的属性
    public MyThread(String name){	//定义构造方法
        this.name=name;
    }
    @Override
    public void run(){				//覆写run()方法,作为线程的主操作方法
        for (int x=0;x<200;x++){
            System.out.println(this.name+"-->"+x);
        }
    }
}
public class Test1 {
    public static void main(String[] args){
        MyThread mt1=new MyThread("线程A");	//实例化多线程对象
        MyThread mt2=new MyThread("线程B");
        MyThread mt3=new MyThread("线程C");
        mt1.start();						//启动多线程
        mt2.start();
        mt3.start();
    }
}
//结果
//线程B-->0
//线程C-->0
//线程A-->0
//线程C-->1
//线程B-->1
//线程C-->2
//后面省略...

Nota: Llamar directamente al método run () no inicia el subprocesamiento múltiple. La única forma de iniciar el subprocesamiento múltiple es el método start () en la clase Thread: public void start () (el cuerpo del método ejecutado al llamar a este método es la definición del método run () Código)

Implemente la interfaz Runnable

La mayor desventaja de la clase Thread para lograr subprocesos múltiples es el problema de la herencia única, por lo que Java también puede usar la interfaz Runnable para lograr subprocesos múltiples. Esta interfaz se define de la siguiente manera:

@FunctionalInterface		//函数式接口
public interface Runnable{
    public void run();
}

Ejemplo: uso de Runnable para lograr subprocesos múltiples

package Project.Study.Multithreading;

class MyTread2 implements Runnable{	//定义线程主体类
    private String name;			//定义类中的属性
    public MyTread2(String name){	//定义构造方法
        this.name=name;
    }
    @Override
    public void run(){				//覆写run()方法
        for(int x=0;x<200;x++){
            System.out.println(this.name+"-->"+x);
        }
    }
}
public class Test2 {
    public static void main(String []args){
        MyTread2 mt1=new MyTread2("线程A");	//实例化多线程类对象
        MyTread2 mt2=new MyTread2("线程B");
        MyTread2 mt3=new MyTread2("线程C");
        new Thread(mt1).start();			//使用Thread启动多线程
        new Thread(mt2).start();
        new Thread(mt3).start();
    }
}
//结果:
//线程C-->0
//线程A-->0
//线程B-->0
//线程A-->1
//线程C-->1
//线程C-->2
//后面省略...

Ejemplo: utilizar la operación de expresión Lambda

package Project.Study.Multithreading;

public class Test2 {
    public static void main(String []args){
        String name="线程对象";
        new Thread(()->{
            for(int x=0;x<200;x++){
                System.out.println(name+"-->"+x);
            }
        }).start();
    }
}
//结果:
//线程对象-->0
//线程对象-->1
//线程对象-->2
//线程对象-->3
//线程对象-->4
//线程对象-->5
//后面省略...

Uso de la interfaz invocable para lograr subprocesos múltiples

La interfaz invocable resuelve el problema de que el método run () en la interfaz Runnable no puede devolver el resultado de la operación.
La definición de esta interfaz es la siguiente:

@FunctionalInterface
public interface Callable{
    public V call() throws Exception;
}

Definir una clase de cuerpo de hilo

import java.util.concurrent.Callable;
class MyThread3 implements Callable<String>{	//多线程主体类
    private int ticket=10;						//卖票
    @Override
    public String call() throws Exception{
        for(int x=0;x<100;x++){
            if(this.ticket>0){					//还有票可以出售
                System.out.println("卖票,ticket="+this.ticket--);
            }
        }
        return "票已卖光!";						//返回结果
    }
}

Cuando se completa la definición de la clase principal de subprocesos múltiples, la clase Thread debe usarse para iniciar el subprocesamiento múltiple, pero no se define ningún constructor en la clase Thread para recibir directamente la instancia del objeto de interfaz invocable, y debido a la necesidad de recibir el valor de retorno del método call () Java proporciona una clase java.util.concurrent.FutureTask <V>, definida de la siguiente manera:

public class FutureTask<V>
extends Object
implements RunnableFuture<V>

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Ejemplo: iniciar múltiples hilos

package Project.Study.Multithreading;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

class MyThread3 implements Callable<String>{
    private int ticket=10;
    @Override
    public String call() throws Exception{
        for(int x=0;x<100;x++){
            if(this.ticket>0){
                System.out.println("卖票,ticket="+this.ticket--);
            }
        }
        return "票已卖光!";
    }
}
public class Test3 {
    public static void main(String []args)throws Exception{
        MyThread3 mt1=new MyThread3();					//实例化多线程对象
        MyThread3 mt2=new MyThread3();
        FutureTask<String>task1=new FutureTask<>(mt1);
        FutureTask<String>task2=new FutureTask<>(mt2);
        //FutureTask是Runnable接口子类,所以可以使用Thread类的构造来接收task对象
        new Thread(task1).start();						//启动第一个多线程
        new Thread(task2).start();						//启动第二个多线程
        //多线程执行完毕后可以取得内容,依靠FutureTask的父接口Future中的get()方法实现
        System.out.println("A线程返回的结果:"+task1.get());
        System.out.println("B线程返回的结果:"+task2.get());
    }
}
//结果:
//卖票,ticket=10
//卖票,ticket=9
//卖票,ticket=10
//卖票,ticket=9
//卖票,ticket=8
//卖票,ticket=8
//卖票,ticket=7
//卖票,ticket=7
//卖票,ticket=6
//卖票,ticket=6
//卖票,ticket=5
//卖票,ticket=5
//卖票,ticket=4
//卖票,ticket=4
//卖票,ticket=3
//卖票,ticket=2
//卖票,ticket=1
//卖票,ticket=3
//卖票,ticket=2
//卖票,ticket=1
//A线程返回的结果:票已卖光!
//B线程返回的结果:票已卖光!

Este programa utiliza la clase FutureTask para implementar una subclase de la interfaz invocable. Dado que FutureTask es una subclase de la interfaz Runnable, puede usar el método start () de la clase Tread para iniciar el subprocesamiento múltiple. Cuando se completa la ejecución del subproceso, puede usar get () en la interfaz Future ) El método devuelve el resultado de ejecución del hilo.

El estado operativo del hilo

Cualquier subproceso generalmente tiene cinco estados, a saber: crear, listo, en ejecución, bloqueado y terminado.
Inserte la descripción de la imagen aquí

1. Crear estado

Después de crear un objeto de subproceso en el programa utilizando el método de construcción, el nuevo objeto de subproceso está en un nuevo estado. En este momento, tiene el espacio de memoria correspondiente y otros recursos, pero todavía está en un estado inoperable.

2. Estado listo

Después de crear un nuevo objeto de hilo, llame al método start () del hilo para iniciar el hilo. Cuando comienza el hilo, el hilo entra en el estado listo. En este punto, el subproceso entrará en la cola del subproceso y esperará el servicio de la CPU, lo que indica que ya tiene las condiciones de ejecución.

3. Estado de ejecución

Cuando se llama al subproceso en el estado listo y obtiene recursos del procesador, el subproceso entra en el estado de ejecución. En este momento, el método run () del objeto thread se llama automáticamente.

4. Estado bloqueado

En ciertas circunstancias especiales, como la suspensión o la necesidad de realizar operaciones de entrada y salida que requieren mucho tiempo, un subproceso en ejecución abandonará la CPU y suspenderá temporalmente su ejecución y entrará en un estado bloqueado. En el estado ejecutable, si llama a sleep (), suspend (), wait () y otros métodos, el hilo entrará en un estado bloqueado. Cuando está congestionado, el hilo no puede entrar en la cola de espera, solo después de que se elimina la causa de la congestión, el hilo puede transferirse al estado preparado.

5. Estado de terminación

Después de que el hilo llama al método stop () o al método run (), está en un estado terminado. El subproceso en el estado terminado no tiene la capacidad de continuar ejecutándose.

49 artículos originales publicados · Me gustó 25 · Visitas 1522

Supongo que te gusta

Origin blog.csdn.net/weixin_45784666/article/details/104957664
Recomendado
Clasificación