El ciclo de vida de un subproceso se refiere a todo el proceso desde la creación hasta la destrucción de un subproceso. Generalmente, existen los siguientes cinco ciclos de vida de un subproceso:
- estado inicial
- estado operativo
- Estado operativo
- estado de sueño
- estado de terminación
Sus transiciones de estado se muestran en el siguiente diagrama:
Ciclo de vida del subproceso de Java
El ciclo de vida de un subproceso de Java es diferente del ciclo de vida mencionado anteriormente, tiene los siguientes seis estados:
- NUEVO (estado de inicialización)
- RUNNABLE (ejecutable/estado en ejecución)
- BLOQUEADO (estado bloqueado)
- ESPERA (estado de espera ilimitado)
- TIMED_WAITING (estado de espera temporizado)
- TERMINADO (estado terminado)
Podemos encontrar estos 6 estados en el código fuente de Thread, de la siguiente manera:
Por supuesto, también puede usar el código Java para imprimir el estado de todos los subprocesos, como se muestra en el siguiente código:
for (Thread.State value : Thread.State.values()) {
System.out.println(value);
}
复制代码
El resultado de la ejecución del programa anterior se muestra en la siguiente figura:
Transición del ciclo de vida
A continuación, hablemos sobre el proceso de conversión del ciclo de vida del subproceso de Java.
1. De NUEVO a FUNCIONABLE
Cuando creamos un hilo, es decir, nuevo Hilo, el hilo está en el estado NUEVO, como se muestra en el siguiente código:
// 创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// ...
}
});
// 获取线程状态
Thread.State state = thread.getState();
System.out.println(state);
复制代码
El resultado de la ejecución del programa anterior se muestra en la siguiente figura:
Sin embargo, después de llamar al método de inicio del subproceso, el estado del subproceso cambia de NUEVO a EJECUTABLE , como se muestra en el siguiente código:
// 创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// 获取到当前执行的线程
Thread currThread = Thread.currentThread();
// 获取线程状态
Thread.State state = currThread.getState();
// 打印线程状态
System.out.println(state);
}
});
thread.start();
复制代码
El resultado de la ejecución del programa anterior se muestra en la siguiente figura:
2. De EJECUTABLE a BLOQUEADO
Cuando el código del subproceso se pone en cola para ejecutarse sincronizadamente, el subproceso cambia del estado EJECUTABLE al estado de bloqueo BLOQUEADO , como se muestra en el siguiente código:
// 创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
// 等待 100 毫秒
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("排队使用锁");
synchronized (ThreadStates.class) {
}
}
});
thread.start();
// 让主线程先得到锁
synchronized (ThreadStates.class) {
// 获取线程状态
Thread.State state = thread.getState();
// 打印线程状态
System.out.println("首次获取线程状态:" + state);
// 休眠 1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 再次获取线程状态
state = thread.getState();
// 打印线程状态
System.out.println("第二次获取线程状态:" + state);
}
复制代码
El resultado de la ejecución del programa anterior se muestra en la siguiente figura:
Cuando un subproceso adquiere un bloqueo sincronizado, pasa del estado BLOQUEADO al estado EJECUTABLE.
3. De EJECUTABLE a ESPERA
Después de que el subproceso llama al método wait(), cambia del estado RUNNABLE al estado de espera indefinido EN ESPERA, de la siguiente manera:
// 创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (this) {
try {
// 线程休眠
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
// 启动线程
thread.start();
// 获取线程状态
Thread.State state = thread.getState();
// 打印线程状态
System.out.println("首次获取线程状态:" + state);
// 休眠 1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取线程状态
state = thread.getState();
// 打印线程状态
System.out.println("第二次获取线程状态:" + state);
复制代码
El resultado de la ejecución del programa anterior se muestra en la siguiente figura:
Cuando se llama al método de notificación/notificación a todos, el subproceso cambiará del estado EN ESPERA al estado EJECUTABLE , como se muestra en el siguiente código:
Object lock = new Object();
// 创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
// 线程休眠
lock.wait();
// 获取当前线程状态
Thread.State state = Thread.currentThread().getState();
// 打印线程状态
System.out.println("获取线程状态:" + state);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
// 启动线程
thread.start();
// 获取线程状态
Thread.State state = thread.getState();
// 打印线程状态
System.out.println("首次获取线程状态:" + state);
// 休眠 1s
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取线程状态
state = thread.getState();
// 打印线程状态
System.out.println("第二次获取线程状态:" + state);
// 唤醒 thread 线程
synchronized (lock) {
lock.notify();
}
复制代码
El resultado de la ejecución del programa anterior se muestra en la siguiente figura:
4. De RUNNABLE a TIMED_WATTING
Al llamar a un método de espera con un tiempo de espera, como dormir (xxx), el subproceso cambiará del estado EJECUTABLE al estado TIMED_WAITING, como se muestra en el siguiente código:
// 创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// 启动线程
thread.start();
// 获取线程状态
Thread.State state = thread.getState();
// 打印线程状态
System.out.println("首次获取线程状态:" + state);
// 休眠 1s
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取线程状态
state = thread.getState();
// 打印线程状态
System.out.println("第二次获取线程状态:" + state);
复制代码
El resultado de la ejecución del programa anterior se muestra en la siguiente figura:
Cuando se excede el período de tiempo de espera, el subproceso cambiará del estado TIMED_WAITING al estado RUNNABLE . El código de implementación es el siguiente:
// 创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
// 获取当前线程状态
Thread.State state = Thread.currentThread().getState();
// 打印线程状态
System.out.println("获取线程状态:" + state);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// 启动线程
thread.start();
// 获取线程状态
Thread.State state = thread.getState();
// 打印线程状态
System.out.println("首次获取线程状态:" + state);
// 休眠 1s
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取线程状态
state = thread.getState();
// 打印线程状态
System.out.println("第二次获取线程状态:" + state);
复制代码
El resultado de la ejecución del programa anterior se muestra en la siguiente figura:
5.EJECUTABLE 到 TERMINADO
Después de ejecutar el subproceso, cambiará del estado EJECUTABLE al estado de destrucción TERMINADO, como se muestra en el siguiente código:
// 创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// 获取当前线程状态
Thread.State state = Thread.currentThread().getState();
// 打印线程状态
System.out.println("获取线程状态:" + state);
}
});
// 启动线程
thread.start();
// 等待 100ms,待线程执行完
Thread.sleep(100);
// 获取线程状态
Thread.State state = thread.getState();
// 打印线程状态
System.out.println("线程状态:" + state);
复制代码
El resultado de la ejecución del programa anterior se muestra en la siguiente figura:
Resumir
Hay 6 tipos de ciclos de vida de subprocesos en Java: NUEVO (estado de inicialización), EJECUTABLE (estado ejecutable/en ejecución), BLOQUEADO (estado de bloqueo), ESPERA (estado de espera ilimitado), TIMED_WAITING (estado de espera cronometrado), TERMINADO (terminación) Expresar). El proceso de conversión del ciclo de vida del hilo se muestra en la siguiente figura:
Enlace original: https://juejin.cn/post/7065856076737937438