Grupo de subprocesos ejecutores para programación concurrente

1. Introducción a Thread Pool

1.1 Grupo de subprocesos:
"Grupo de subprocesos", como su nombre lo indica, es un caché de subprocesos. El subproceso es un recurso escaso. Si se crea sin restricciones, no solo consumirá recursos del sistema, sino que también reducirá la estabilidad del sistema. Por lo tanto, Java proporciona un grupo de subprocesos para subprocesos Asignación, ajuste y supervisión unificados;
1.2 Introducción a los grupos de subprocesos
En el desarrollo web, el servidor necesita aceptar y procesar solicitudes, por lo que se asigna un subproceso para procesar una solicitud. Si se crea un nuevo subproceso para cada solicitud, es muy fácil de implementar, pero hay un problema: si el número de solicitudes simultáneas es muy grande, pero el tiempo de ejecución de cada subproceso es muy corto, entonces se crearán subprocesos y destruido con frecuencia Reducirá en gran medida la eficiencia del sistema. Puede parecer que el servidor dedica más tiempo y recursos del sistema a crear nuevos subprocesos y destruirlos para cada solicitud que a procesar las solicitudes reales de los usuarios. Entonces, ¿hay alguna manera de ejecutar una tarea sin ser destruida, pero puede continuar realizando otras tareas? Este es el propósito del grupo de subprocesos. El grupo de subprocesos proporciona una solución al problema de la sobrecarga del ciclo de vida del subproceso y la escasez de recursos. Al reutilizar subprocesos para varias tareas, la sobrecarga de la creación de subprocesos se amortiza en varias tareas.
1.3 ¿Cuándo usar el grupo de subprocesos?

  • El tiempo de procesamiento de una sola tarea es relativamente corto
  • La cantidad de tareas que deben procesarse es grande
    1.4 Ventajas de Thread Pool
  • Reutilice subprocesos existentes, reduzca la sobrecarga de creación y muerte de subprocesos y mejore el rendimiento
  • Mejora la velocidad de respuesta. Cuando llega la tarea, la tarea se puede ejecutar inmediatamente sin esperar hasta que se cree el hilo.
  • Mejorar la capacidad de administración de los subprocesos. Los subprocesos son recursos escasos. Si se crean de forma ilimitada, no solo consumirán recursos del sistema, sino que también reducirán la estabilidad del sistema. El grupo de subprocesos se puede utilizar para una asignación, ajuste y supervisión uniformes.

Marco 2.Executor

Diagrama de clases de ejecutor
La interfaz Executor es la parte más básica del marco del grupo de subprocesos. Define un método de ejecución para ejecutar Runnable.
ExecutorService es una subinterfaz general; se definen métodos importantes:

public interface ExecutorService extends Executor {
    
    

    //在完成已提交的任务后封闭办事,不再接管新任务
    void shutdown();

    //停止所有正在履行的任务并封闭办事
    List<Runnable> shutdownNow();

	//测试是否该ExecutorService已被关闭
    boolean isShutdown();
	//测试是否所有任务都履行完毕了
    boolean isTerminated();

    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;

	//可用来提交Callable或Runnable任务,并返回代表此任务的Future对象
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);


    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;


    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException;

    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;

    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

2.1 Hay 5 estados de grupo de subprocesos

RUNNING    = ­1 << COUNT_BITS; //高3位为111
SHUTDOWN   =  0 << COUNT_BITS; //高3位为000
STOP       =  1 << COUNT_BITS; //高3位为001
TIDYING    =  2 << COUNT_BITS; //高3位为010
TERMINATED =  3 << COUNT_BITS; //高3位为011

1 、 CORRER

  1. Descripción del estado: cuando el grupo de subprocesos está en estado EJECUTANDO, puede recibir nuevas tareas y procesar las tareas agregadas.
  2. Cambio de estado: el estado de inicialización del grupo de subprocesos está EN EJECUCIÓN. En otras palabras, una vez que se crea el grupo de subprocesos, está en el estado EJECUTANDO y el número de tareas en el grupo de subprocesos es 0.
    2. APAGADO
  3. Descripción del estado: cuando el grupo de subprocesos está en el estado APAGADO, no recibe nuevas tareas, pero puede procesar las tareas agregadas.
  4. Cambio de estado: cuando se llama a la interfaz shutdown () del grupo de subprocesos, el grupo de subprocesos cambia de EJECUTANDO -> APAGADO.
    3. DETENER
  5. Descripción del estado: cuando el grupo de subprocesos está en el estado STOP, no recibe nuevas tareas, no procesa las tareas agregadas e interrumpe las tareas que se están procesando.
  6. Cambio de estado: cuando se llama a la interfaz shutdownNow () del grupo de subprocesos, el grupo de subprocesos cambia de (EN EJECUCIÓN o APAGADO) -> DETENER.
    4. ORDEN
  7. Descripción del estado: cuando todas las tareas hayan finalizado y el "número de tareas" registrado por ctl sea 0, el grupo de subprocesos se convertirá en TIDYING. Cuando el grupo de subprocesos se convierte en TIDYING, se ejecutará la función de gancho terminated (). terminated () está vacío en la clase ThreadPoolExecutor.Si el usuario desea realizar el procesamiento correspondiente cuando el grupo de subprocesos se convierte en TIDYING, se puede lograr sobrecargando la función terminated ().
  8. Cambio de estado: cuando el grupo de subprocesos está en el estado APAGADO, la cola de bloqueo está vacía y las tareas ejecutadas en el grupo de subprocesos también están vacías, será APAGADO -> ORDEN. Cuando el grupo de subprocesos está en el estado STOP, cuando las tareas ejecutadas en el grupo de subprocesos están vacías, será STOP -> TIDYING.
    5. TERMINADO
  9. Descripción del estado: el grupo de subprocesos finaliza por completo y se convierte en el estado TERMINADO.
  10. Cambio de estado: cuando el grupo de subprocesos está en el estado TIDYING, después de la ejecución de terminado (), será TIDYING -> TERMINATED.
    Las condiciones para ingresar a TERMINADO son las siguientes:
  • El grupo de subprocesos no está en estado EJECUTANDO;
  • El estado del grupo de subprocesos no es el estado TIDYING ni el estado TERMINATED;
  • Si el estado del grupo de subprocesos es APAGADO y workerQueue está vacío;
  • workerCount es 0;
  • Se estableció correctamente el estado TIDYING.

3. Creación de grupos de subprocesos:

porEjecutoresIntroducción a los tipos de grupos de subprocesos creados por API:
3.1 Un número fijo de grupos de subprocesos

    /**
    *创建重复使用固定数量线程的线程池
	*使用提供的
	*在需要时创建新线程的ThreadFactory。在任何时候,
	*最多{@code nThreads}线程将处于活动处理状态
	*任务。如果在所有线程
	*活动,它们将在队列中等待线程
	*可用。如果任何线程在
	*在关闭之前执行,如果
	*需要执行后续任务。池中的线程将
	*存在,直到显式{@ Link ExcutoService }shutdown
    * shutdown}.
	*@param nThreads 线程池中的线程数
	*@param threadFactory创建新线程时要使用的工厂
	*@return 返回新创建的线程池
	*@threadFactory为空时抛出NullPointerException
	*如果{@code nThreads<=0},则@throws IllegalArgumentException
     */
    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    
    
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
    }

3.2. Grupo de subprocesos paralelos
Este es el grupo de subprocesos recién agregado en 1.8, puede ver que las operaciones relacionadas con ForkJoin se utilizan principalmente

    /**
     * 并行线程池
     * 作为其目标并行级别。
	 *@返回新创建的线程池
     * @see #newWorkStealingPool(int)
     * @since 1.8
     */
    public static ExecutorService newWorkStealingPool() {
    
    
        return new ForkJoinPool
            (Runtime.getRuntime().availableProcessors(),
             ForkJoinPool.defaultForkJoinWorkerThreadFactory,
             null, true);
    }

3. Grupo de subprocesos con un solo subproceso
De hecho, esto no se puede llamar grupo de subprocesos, porque solo hay un subproceso. Hilo principal = Hilo máximo = 1, esto es más adecuado para escenarios que necesitan garantizar la ejecución secuencial de tareas en la cola.

    /**
	*创建使用单个工作线程操作的执行器
	*从无限的队列中。(但请注意,如果
	*线程在执行之前由于失败而终止
	*关闭,如果需要执行新的
	*后续任务。)保证执行任务
	*按顺序,任何时候都不会有多个任务处于活动状态
	*给定的时间。与其他等价物不同
	*{@code newFixedThreadPool(1)}返回的执行器是
	*保证不可重新配置以使用其他线程。
     *
     * @return the newly created single-threaded Executor
     */
    public static ExecutorService newSingleThreadExecutor() {
    
    
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

4. Grupo de subprocesos de caché
Crea subprocesos según sea necesario. No hay subproceso principal. Cuando no hay tareas en los 60, los subprocesos supervivientes se reciclarán. Cuando hay tareas en los 60, puede reutilizar los subprocesos existentes. Tenga en cuenta que su cola de trabajo es SynchronousQueue, aquí hay una breve introducción), cada una de sus operaciones de colocación debe esperar a la operación de toma, lo que significa que si la velocidad de producción de la tarea es mayor que la velocidad de consumo, entonces no creará un nuevo hilo. . Este grupo de subprocesos es adecuado para escenarios en los que se realizan una gran cantidad de pequeñas tareas.

    /**
	*创建根据需要创建新线程的线程池,但是
	*将重用以前构造的线程
	*可用。这些池通常会提高性能
	*执行许多短期异步任务的程序。
	*对{@code execute}的调用将重用先前构造的
	*线程(如果可用)。如果没有现有线程可用,则新建
	*将创建线程并将其添加到池中。具有
	*60秒未使用被终止并从
	*缓存。因此,一个空闲时间足够长的池将
	*不消耗任何资源。请注意,与
	*属性,但有不同的详细信息(例如,超时参数)
	*可以使用{@link ThreadPoolExecutor}构造函数创建。
     * @return the newly created thread pool
     */
    public static ExecutorService newCachedThreadPool() {
    
    
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

5. El grupo de subprocesos retrasados
ScheduledThreadPoolExecutor hereda ThreadPoolExecutor, por lo que super eventualmente se transferirá al constructor de ThreadPoolExecutor. Se puede ver que el número máximo de subprocesos es el valor máximo de int, y la cola de trabajo es DelayedWorkQueue. El grupo de subprocesos es adecuado para ejecutar tareas retrasadas.

    /**
	*创建可以调度命令的单线程执行器
	*在给定的延迟后运行,或周期性地执行。
	*(但请注意,如果
	*线程在执行之前由于失败而终止
	*关闭,如果需要执行新的
	*后续任务。)保证执行任务
	*按顺序,任何时候都不会有多个任务处于活动状态
	*给定的时间。与其他等价物不同
	*{@code newScheduledThreadPool(1)}返回的执行器是
	*保证不可重新配置以使用其他线程。
	*@返回新创建的计划执行器
     */
    public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    
    
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1));
    }
        public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
    
    
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1, threadFactory));
    }

Supongo que te gusta

Origin blog.csdn.net/qq_38130094/article/details/104165504
Recomendado
Clasificación