Java Foundation-thread y concurrencia

Hilo y Hilo concurrente

Conceptos basicos

Programa: un conjunto de instrucciones que una computadora puede reconocer y ejecutar es un código estático.

Proceso: una actividad en ejecución de un programa, un programa en ejecución.

Hilo: Un componente de un proceso, representa un flujo secuencial de ejecución.


Proceso de contacto de hilo:

① El subproceso es la unidad de ejecución y asignación más pequeña de un proceso. No puede moverse de forma independiente y debe depender del proceso. Numerosos hilos conforman el proceso.

② Los recursos se asignan al proceso, y todos los hilos del mismo proceso comparten todos los recursos del proceso.

image-20200412123650498

Diferencia de hilo de proceso:

① Programación: Thread es la unidad básica para la programación y la asignación, y Process es la unidad básica para poseer recursos

② Concurrencia: no solo los procesos se pueden ejecutar simultáneamente, sino que también se pueden ejecutar varios subprocesos del mismo proceso simultáneamente

③ Poseer recursos: un proceso es una unidad independiente que posee recursos. Los subprocesos no poseen recursos del sistema, pero pueden acceder a recursos que pertenecen a procesos

Overhead Gastos generales del sistema: al crear o cancelar un proceso, porque el sistema tiene que asignar y reclamar recursos para él,

La sobrecarga del sistema es significativamente mayor que la sobrecarga de crear o deshacer subprocesos, por lo que el uso de subprocesos múltiples puede reducir la sobrecarga de recursos

Ciclo de vida

image-20200412123305286

  • Estado de primer año:

    Después de crear un objeto de subproceso utilizando la nueva palabra clave y la clase de subproceso o sus subclases, el objeto de subproceso está en un nuevo estado. Permanece en este estado hasta que el programa inicia () este hilo.


  • Estado listo:

    Cuando el objeto thread llama al método start (), el thread entra en el estado listo. El subproceso en el estado listo está en la cola de espera, esperando ser programado por el planificador de subprocesos en la JVM.


  • Estado de funcionamiento:

    Si el subproceso en el estado preparado adquiere recursos de CPU, puede ejecutar run () y el subproceso ahora está en estado de ejecución. El subproceso en estado de ejecución es el más complejo: puede bloquearse, estar listo y morir.


  • Estado de bloqueo:

    Si un subproceso ejecuta los métodos de suspensión, suspensión, etc., y pierde los recursos ocupados, el subproceso ingresa al estado bloqueado desde el estado de ejecución. Puede volver a ingresar al estado listo después de que haya expirado el tiempo de suspensión o después de obtener los recursos del dispositivo. Se puede dividir en tres tipos:

    • Esperando bloqueo: el hilo en el estado de ejecución ejecuta el método wait () para hacer que el hilo entre en el estado de espera de bloqueo.

    • Bloqueo de sincronización: el subproceso no puede adquirir el bloqueo sincronizado (porque el bloqueo está ocupado por otros subprocesos).

    • Otro bloqueo: cuando se emite una solicitud de E / S llamando al sleep () o join () del thread, el thread ingresará al estado de bloqueo,

      Cuando el estado de suspensión () se agota, join () espera a que el subproceso termine o agote el tiempo de espera, o el proceso de E / S se completa y el subproceso vuelve a entrar en el estado listo.


  • Estado de la muerte:

    Cuando un hilo en estado de ejecución completa una tarea u otra condición de terminación, el hilo cambia al estado de terminación.

Cómo crear hilos

Heredar clase de subproceso

1. Defina una subclase que herede Thread

2. Las subclases anulan el método de ejecución de Thread

3. Instanciar objetos de subclase y crear hilos

4. Llame al método de inicio para iniciar el hilo


Código fuente

public class TestThread {
    public static void main(String[] args) {
        //创建线程方法1 继承Thread,重写run
        NewThread thread = new NewThread();
        thread.start();
        System.out.println("主线程开始打印数据");
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程:"+i);
        }
    }
}

class NewThread extends Thread{
    @Override
    public void run() {
        System.out.println("分支线程开始打印数据");
        for (int i = 0; i < 5; i++) {
            System.out.println("分支线程:"+i);
        }
    }
}

Ejecute el programa varias veces y descubra que los resultados obtenidos por la consola son diferentes. Esta es la aleatoriedad de la programación de la CPU.

Implemente la interfaz Runnable

1. Defina una subclase que implemente la interfaz Runnable

2. La subclase implementa el método de ejecución de Runnable

3. Cree un objeto de hilo a través del constructor de clase Thread

4. Pase la instancia Runnable como argumento al constructor

5. Llame al método de inicio de la instancia de Thread para iniciar el thread


Código fuente

public class TestThread {
    public static void main(String[] args) {
        //创建线程方法2 实现Runnable接口
        Thread thread = new Thread(new NewRunnable());
        thread.start();
        System.out.println("主线程开始打印数据");
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程:"+i);
        }
    }
}

class NewRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("分支线程开始打印数据");
        for (int i = 0; i < 5; i++) {
            System.out.println("分支线程:"+i);
        }
    }
}

La diferencia entre los dos métodos de creación.

  1. Al crear varios subprocesos mediante la implementación de la interfaz Runnable, la clase de subproceso solo implementa la interfaz Runnable y también puede heredar otras clases. (Recomendado)
  2. Varios subprocesos pueden compartir el mismo objeto de clase de implementación Runnable, que conduce a la sincronización de recursos.
  3. Al crear subprocesos múltiples heredando la clase Thread, si necesita acceder al hilo actual, úselo directamente para obtener el hilo actual.

Clase de hilo

Método de construcción


image-20200412131959700


Métodos comunes

Método Descripción funcional
inicio nulo público () Este hilo comienza a ejecutarse; la máquina virtual Java llama al método de ejecución del hilo.
vacío público run () Si el subproceso se construye utilizando un objeto de ejecución Runnable independiente, se llama al método de ejecución del objeto Runnable; de ​​lo contrario, el método no hace nada y regresa.
public final void setName (nombre de cadena) Cambie el nombre del hilo para que sea el mismo que el nombre del parámetro.
public final void setPriority (int prioridad) Cambiar la prioridad del hilo.
public final void setDaemon (booleano encendido) Marque el hilo como un hilo de demonio o hilo de usuario.
unión nula pública final (milisegundos largos) El tiempo máximo de espera para que este subproceso termine es de milis milisegundos.
interrupción pública nula () Interrumpir el hilo. stop () está obsoleto.
public boolean final isAlive () Prueba si el hilo está activo.
unión vacía final pública sincronizada (long millis) El tiempo máximo de espera para que este subproceso termine es de milis milisegundos.
rendimiento vacío público estático () El subproceso cede, suspende el objeto de subproceso que se está ejecutando actualmente y ejecuta otros subprocesos.
sueño vacío público estático (milisegundos largos) Suspenda el subproceso que se está ejecutando actualmente (suspender la ejecución) dentro del número especificado de milisegundos.
Hilo público estático currentThread () Devuelve una referencia al objeto de hilo actualmente en ejecución.

Prioridad

 /**  * The minimum priority that a thread can have.  */ 
public final static int MIN_PRIORITY = 1;

/**  * The default priority that is assigned to a thread.  */ 
public final static int NORM_PRIORITY = 5; 

/**  * The maximum priority that a thread can have.  */ 
public final static int MAX_PRIORITY = 10;

El rango es de 1 a 10. Cuanto mayor sea el número, mayor será la probabilidad de llamadas del sistema. La prioridad predeterminada es 5.


Código de prueba de ejemplo

public class FunctionTest {
    public static void main(String[] args) throws InterruptedException {
        Thread threadChild = new NewThread();
        Thread threadRun = new Thread(new NewRunnable(),"线程2  ");
		//先设置优先级
        threadChild.setPriority(1);
        threadRun.setPriority(10);
		//启动线程
        threadChild.start();
        threadRun.start();
		//获取线程属性
        threadChild.setName("线程1  ");
        System.out.println(threadChild.getName());
        System.out.println(threadRun.getName());
        System.out.println(Thread.currentThread().getName());

        if (threadChild.isAlive())
            System.out.println(threadChild.getName()+"活着");

        System.out.println("------有人在中间插队------");
        threadChild.join();//执行完毕才到下一行
        System.out.println("------有人在中间插队------");
		//打印线程状态
        threadRun.interrupt();
        System.out.println(threadChild.isAlive());
        System.out.println(threadRun.isAlive());

    }
}

Postdata

Lo anterior es solo una comprensión conceptual muy básica.

Se encontrarán muchos problemas en aplicaciones prácticas, como:

  • Hilo de sincronización
  • Comunicación entre hilos
  • Hilo estancado
  • Control de subprocesos: suspender, detener y reanudar

Supongo que te gusta

Origin www.cnblogs.com/1101-/p/12684973.html
Recomendado
Clasificación