Explicación detallada del ciclo de vida del subproceso de Java

prefacio

El ciclo de vida del subproceso en Java es el concepto central del desarrollo de subprocesos múltiples. Comprender el ciclo de vida de los subprocesos y cómo experimentan las transiciones de estado es fundamental para escribir programas multiproceso eficientes y sin errores.

1. Ciclo de vida del hilo

Los subprocesos de Java tienen principalmente los siguientes estados, que se definen en la clase de enumeración Thread.State:

  1. Nuevo estado (Nuevo) : cuando creamos una nueva instancia de hilo, el hilo está en el nuevo estado. En este momento, start()no se ha llamado al método del subproceso y aún no se ha iniciado la ejecución del objeto del subproceso. En este estado, la máquina virtual de Java (JVM) ha asignado la memoria necesaria para este subproceso.

    Thread t = new Thread(); // 线程此时处于New状态
    
  2. Estado listo (ejecutable) : cuando el objeto de hilo llama start()al método, el hilo está en estado listo. Un subproceso en estado listo puede comenzar a ejecutarse después de obtener un segmento de tiempo de CPU. El subproceso en este estado se encuentra en el grupo de subprocesos ejecutables, a la espera de ser seleccionado por la programación de subprocesos para obtener el derecho a utilizar la CPU.

    t.start(); // 线程此时处于Runnable状态
    
  3. Estado de ejecución (Running) : después de que el subproceso obtiene el segmento de tiempo de la CPU, ingresa al estado de ejecución y comienza a ejecutar run()el código en el método. Vale la pena señalar que la velocidad y la eficiencia reales de la ejecución del código están relacionadas con la velocidad del procesador y la cantidad de núcleos en un procesador multinúcleo.

    public void run() {
          
          
        System.out.println("Thread is running.");
    }
    // 如果此时这个方法正在执行,那么线程就处于Running状态
    
  4. Estado bloqueado (Bloqueado) : cuando un subproceso intenta adquirir un bloqueo de objeto interno (es decir, ingresar un synchronizedbloque), y el bloqueo está en manos de otros subprocesos, el subproceso ingresa al estado bloqueado. Un subproceso en estado bloqueado entrará en estado listo cuando se libere el bloqueo.

    synchronized(object) {
          
          
        // 如果此时object的锁被其他线程持有,那么线程就处于Blocked状态
    }
    
  5. En espera : un subproceso puede entrar en estado de espera llamando a su propio wait()método, join()método o LockSupport.park()método, o llamando a un método de otro subproceso . join()A los subprocesos en estado de espera no se les asignan segmentos de tiempo de CPU, solo pueden ingresar al estado listo si otros subprocesos los despiertan explícitamente.

    t.wait();  // 线程此时处于Waiting状态
    t.join();  // 线程此时处于Waiting状态
    
  6. Estado de espera temporizada (Timed Waiting) : cuando un subproceso llama a sleep(long ms), wait(long ms), join(long ms)o LockSupport.parkNanos(), LockSupport.parkUntil()etc. un método con un tiempo de espera especificado, el subproceso entrará en el estado de espera temporizada. Cuando expira el tiempo de espera, el subproceso vuelve automáticamente al estado listo.

    Thread.sleep(1000); // 线程此时处于Timed Waiting状态
    
  7. Estado terminado : cuando run()se ejecuta el método del subproceso o se interrumpe el subproceso, el subproceso entrará en el estado terminado. En este estado, el subproceso ha completado todo su trabajo.

    // 当run()方法执行完毕,线程处于Terminated状态
    public void run() {
          
          
        System.out.println("Thread is running.");
    }
    

La transición entre estos estados se realiza llamando a varios métodos. A continuación veremos los detalles de estas transiciones de estado.

2. Transición de estado de hilo

inserte la descripción de la imagen aquí

La transición del estado del hilo es una parte muy importante. Comprender la transición entre estados nos ayuda a comprender y dominar mejor el comportamiento de los hilos. A continuación, echemos un vistazo a las transiciones de varios estados de subprocesos en Java.

  1. Nuevo estado a estado listo : cuando se crea el objeto de subproceso, ingresa al nuevo estado. En este momento, llamando start()al método del objeto de subproceso, el subproceso puede entrar en el estado listo y esperar a que el programador de subprocesos del sistema programe.

    Thread t = new Thread(); // 新建状态
    t.start(); // 调用start()方法,线程进入就绪状态
    
  2. Estado listo a estado en ejecución : el programador de subprocesos selecciona un subproceso de la cola lista y le asigna recursos de CPU, y el subproceso cambia del estado listo al estado en ejecución.

  3. El estado de ejecución cambia al estado listo : cuando un subproceso en el estado de ejecución llama a yield()un método, o el tiempo de ejecución del subproceso excede el intervalo de tiempo especificado por el sistema, el subproceso liberará recursos de CPU, cambiará del estado de ejecución a el estado listo y espere a que el sistema vuelva a programar.

    Thread.yield(); // 调用yield()方法,线程从运行状态进入就绪状态
    
  4. Estado de ejecución a estado bloqueado : cuando un subproceso en estado de ejecución intenta adquirir un bloqueo de objeto retenido por otros subprocesos, el subproceso entrará en estado bloqueado.

    synchronized(object) {
          
          
        // 如果此时object的锁被其他线程持有,那么线程就从运行状态进入阻塞状态
    }
    
  5. Estado bloqueado a estado listo : cuando un subproceso en estado bloqueado adquiere el bloqueo de objeto liberado por otros subprocesos, el subproceso cambia del estado bloqueado al estado listo y espera a que el sistema vuelva a programar.

  6. Estado de ejecución a estado de espera : cuando un subproceso en estado de ejecución llama wait()al método join()o LockSupport.park(), el subproceso entrará en estado de espera. Los subprocesos en estado de espera deben depender de las notificaciones de otros subprocesos para volver al estado listo.

    t.wait(); // 调用wait()方法,线程从运行状态进入等待状态
    t.join(); // 调用join()方法,线程从运行状态进入等待状态
    
  7. Estado de espera a estado listo : cuando un subproceso en estado de espera es llamado notify()o notifyAll()despertado por otros subprocesos, o es interrumpido por otros subprocesos, o el tiempo de espera expira, el subproceso cambia del estado de espera al estado listo.

    t.notify(); // notify()方法被调用,线程从等待状态进入就绪状态
    
  8. El estado de ejecución cambia al estado de espera de tiempo de espera : cuando un subproceso en el estado de ejecución llama al método sleep(), wait(), join()o con un parámetro de tiempo de espera, el subproceso entrará en el estado de espera de tiempo de espera.LockSupport.parkNanos()LockSupport.parkUntil()

    Thread.sleep(1000); // 调用sleep()方法,线程从运行状态进入超时等待状态
    
  9. Estado de espera de tiempo de espera a estado listo : cuando el tiempo de espera de un subproceso en el estado de espera de tiempo de espera expira, o es activado o interrumpido por otros subprocesos, el subproceso cambiará del estado de espera de tiempo de espera al estado listo.

  10. De cualquier estado a estado terminado : cuando un subproceso completa su tarea o sale debido a una excepción, ingresa al estado terminado.

Al comprender las transiciones de estado de los subprocesos anteriores, puede obtener una comprensión más profunda del mecanismo operativo de los subprocesos y proporcionar una base teórica para la programación de subprocesos múltiples.

3. Ejemplo de ciclo de vida del hilo

El siguiente ejemplo de código Java demuestra todo el proceso de un subproceso desde la creación hasta la finalización:

// 创建一个继承了Thread类的ExampleThread类
class ExampleThread extends Thread {
    
    
    private Object lock; // 创建一个私有的Object对象,它将在同步代码块中被使用作为锁

    // 构造函数,接受一个Object类型的参数
    public ExampleThread(Object lock) {
    
    
        this.lock = lock; // 将传入的对象赋值给lock
    }

    // 重写Thread类的run方法
    @Override
    public void run() {
    
    
        // 同步代码块,只有获取到lock对象的锁才能执行
        synchronized(lock) {
    
    
            try {
    
    
                // 输出线程名和状态
                System.out.println(Thread.currentThread().getName() + " is running");
                // 让线程睡眠1秒,此时线程进入TIMED_WAITING状态
                Thread.sleep(1000);

                // 输出线程名和状态
                System.out.println(Thread.currentThread().getName() + " is waiting");
                // 调用wait()方法,线程释放lock锁,进入WAITING状态
                lock.wait();

                // 线程被唤醒,获取到lock锁,输出线程名和状态
                System.out.println(Thread.currentThread().getName() + " is running again");
            } catch (InterruptedException e) {
    
    
                // 线程被中断,输出线程名和状态,然后线程将结束
                System.out.println(Thread.currentThread().getName() + " is interrupted and will terminate");
            }
        }
    }
}

public class Main {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        // 创建一个共享的锁对象
        Object lock = new Object();

        // 创建一个新的线程(NEW状态)
        Thread t1 = new ExampleThread(lock);
        System.out.println(t1.getName() + " is created");

        // 启动新的线程(READY/RUNNABLE状态)
        t1.start();

        // 让主线程睡眠2秒,这样新线程就可以先运行
        Thread.sleep(2000);

        // 唤醒等待的线程(将进入READY/RUNNABLE状态)
        synchronized(lock) {
    
    
            lock.notify();
        }

        // 让主线程再睡眠1秒,这样被唤醒的线程可以完成运行
        Thread.sleep(1000);
    }
}

Este ejemplo de código demuestra todo el proceso de un subproceso de Java, desde que se crea (estado NUEVO), hasta que está listo y se ejecuta (estado LISTO/EJECUTABLE), espera (estado EN ESPERA), se activa y se ejecuta nuevamente y finalmente finaliza (TERMINADO). estado).
para optimizar el rendimiento de la aplicación.

conclusión

Espero que el contenido anterior pueda ayudarlo a comprender el ciclo de vida de los subprocesos de Java. Comprender el ciclo de vida del subproceso es muy importante para escribir programas concurrentes y para la programación multiproceso. Recuerda, la mejor manera de aprender es haciendo. Por lo tanto, lo animo a que pruebe el código anterior usted mismo para obtener una comprensión más profunda de cada etapa del ciclo de vida del subproceso.

Supongo que te gusta

Origin blog.csdn.net/weixin_46703995/article/details/131263544
Recomendado
Clasificación