Recientemente, encontré un nuevo requisito en el proyecto, que es implementar una función que pueda agregar dinámicamente tareas cronometradas. Hablando de esto, algunas personas pueden decir que es simple, solo usa cuarzo, es simple y crudo. Sin embargo, el marco de cuarzo es demasiado pesado, y los proyectos pequeños no son fáciles de operar. Por supuesto, algunas personas pueden decir que JDK proporciona interfaz de temporizador, que es completamente suficiente. Sin embargo, los requisitos de nuestro proyecto son modelos completamente de múltiples subprocesos, mientras que el temporizador es de un solo hilo, por lo tanto, y el autor finalmente eligió el grupo de hilo de JDK.
¿Qué es una piscina de hilo?
Java proporciona cuatro tipos de grupos de hilos a través de ejecutores, a saber:
NewCachedThreadPool: cree una piscina de hilos en caché. Si la longitud del grupo de roscas excede las necesidades de procesamiento, puede reciclar de manera flexible hilos inactivos. Si no hay reciclaje, cree un nuevo hilo.
NewFixedThreadPool: crea un grupo de subprocesos de longitud fija que puede controlar el número máximo de concurrencia de subprocesos, y los hilos excesivos esperarán en la cola.
NewsCheduledThreadPool: Crea un grupo de hilos de longitud fija que admite la ejecución de tareas cronometradas y periódicas.
NewsingLethreadExecutor: Crea un grupo de hilos de un solo hilo, que solo usará un hilo de trabajador único para ejecutar tareas, asegurando que todas las tareas se ejecuten en el orden especificado (FIFO, LIFO, prioridad).
El póster utiliza NewsCheduledThreadPool en el proyecto. Eso es todo. No importa cuántos póster seas, mostrarás tus habilidades. Google y es mucho.
Obtener servicio de piscina de subprocesos
El autor usa el modo Singleton para obtener el servicio del grupo de subprocesos. El código es el siguiente:
/*** Creación de la piscina de hilos. * @author wuhf * @date 2018/01/16 */public class ThreadPoolUtils {private static shatedExedExecutorService ExecutorService; Private ThreadPoolUtils () {// Crea un grupo de subprocesos manualmente. EjecutorService = new ScheduledThreadPoolExecutor (10, nuevo BasicThreadFactory.Builder (). NamingPattern ("SyncData-schedule-pool-%d"). Daemon (true) .Build ()); } clase privada de clase estática plugInConFigholder {private final de threadpoolutils instancia = new ThreadPoolUtils (); } public static threadpoolUtils getInStance () {return plugInConFigholder.Instance; } public ScheduledExecutorService getThreadPool () {return EjecutorService; }}Interrumpir una implementación de código de subproceso en ejecución
No diré muchas tonterías, el código es el siguiente:
/*** Se interrumpe una tarea en el grupo de subprocesos. */public class InterruptHread implementos runnable {private int num; Public InterruptHread (int num) {this.num = num; } public static void main (string [] args) lanza interruptedException {hilo interrumptHread = new Thread (new InterruptHread (1)); ProchuledFuture <?> T = ThreadPoolUtils.getInStance (). GetThreadPool (). ScheduleAtFixedRate (interruptThread, 0,2, TimeUnit.seconds); InterruptHread InterruptHread1 = new InterruptHread (2); ThreadPoolUtils.getInstance (). GetThreadPool (). ScheduleAtFixedRate (interruptThread1,0,2, TimeUnit.seconds); InterruptHread InterruptHread2 = new InterruptHread (3); ThreadPoolUtils.getInstance (). GetThreadPool (). ScheduleAtFixedRate (interruptThread2,0,2, TimeUnit.seconds); Thread.sleep (5000); // Terminar el hilo de ejecución interrupthread t.cancel (true); while (true) {}} @Override public void run () {System.out.println ("Este es un hilo" + num); }}Récord atrapado
Cuando el póster estaba usando el siguiente código, de repente pensó en cómo evitar que el hilo se ejecute cuando se debe detener esta tarea de tiempo.
ThreadPoolUtils.getInstance (). GetThreadPool (). ScheduleAtFixedRate (InterruptHread, 0,2, TimeUnit.seconds);
Como tengo tanta necesidad, vamos a buscarlo en Google. Después de buscar la mayor parte del tiempo, no pude encontrar ninguna información relevante. Todos fueron un análisis en profundidad del grupo de hilos Java. O variables globales o algo así, no se encontró ninguna solución para satisfacer al autor.
Dado que no hay hilo, echemos un vistazo al código fuente subyacente de ScheduleAtFixedRate para ver qué es. Como se esperaba, vi la implementación específica del método ScheduleAtFixedRate en el código fuente y descubrí que su valor de retorno es programado.
Public ProchuledFuture <?> scheduleatFixedRate (comando runnable, long initialDelay, período largo, unidad de tiempo de tiempo) {if (command == null || unit == null) tirar nueva nullPointerException (); if (período <= 0) tirar nueva ilegalargumentException (); ProchuledFutureTask <Void> sft = new ProchuledFutureTask <Void> (comando, nulo, Triggertime (initialDelay, unit), unit.tonanos (período)); Runnablescheduledfuture <Void> t = decorAtTask (comando, sft); sft.outertask = t; DeletedExecute (t); regresar t; }Entonces echemos un vistazo a lo que hay dentro de lafuture programado. No decepcionó el póster, y vi esto
Public Boolean Cancel (boolean MayInterruptiNning) {boolean cancelado = super.cancel (MayInterruptUrfrunning); if (cancelado && removeOnCancel && HeapIndex> = 0) eliminar (esto); return cancelado;} // Eliminar el hilo actual de la cola de hilo en ejecución pública boolean eliminar (tarea runnable) {boolean eliminado = workqueue.remove (tarea); try termine (); // en caso de cierre y ahora el retorno vacío eliminado;}Vamos a ver qué es Super.Cancel (MayInterruptiRifrunning). Vemos esto.
// Detenga el hilo en ejecución llamando al método de interrupción del hilo public boolean Cancel (boolean MayInterruptiNning) {if (! (State == new && unsafe.compareanddswapint (this, stateOffset, nuevo, MayInterruptiNning? Interrupting: Canceled)) Devuelve falso; Pruebe {// en caso de llamar para interrumpir la excepción si (mayinterruptifrunning) {try {hilo t = runner; if (t! = null) t.interrupt (); } Finalmente {// State final unsafe.putOrderedInt (this, stateOffset, interrumpido); }}} Finalmente {finkcompletion (); } return verdadero; }Todos los problemas aquí están resueltos.
Resumimos
Siempre hay soluciones difíciles en los proyectos. Cuando Google no es fácil de encontrar, puede ser una buena manera de buscar el código fuente de JDK.