¿Qué es ExecutorService en Java y cómo crearlo?



Este artículo cubre el concepto de la subinterfaz Executor ExecutorService en Java con varios ejemplos para explicar la creación y administración de subprocesos en Java.

El lenguaje de programación Java funciona de manera muy eficiente con aplicaciones que requieren que las tareas se ejecuten simultáneamente en un hilo. Se vuelve difícil para cualquier aplicación ejecutar una gran cantidad de subprocesos simultáneamente. Entonces, para superar este problema, viene con ExecutorService, que es una subinterfaz del . En este artículo, discutiremos la funcionalidad de ExecutorService en Java. Los siguientes son los temas cubiertos en este blog:

¿Qué es Executor Framework?

Es bastante más fácil hacer y ejecutar uno o dos hilos simultáneamente. Pero se vuelve difícil cuando el número de subprocesos aumenta a un número significativo. Las aplicaciones grandes de subprocesos múltiples tendrán cientos de subprocesos ejecutándose simultáneamente. Por lo tanto, tiene mucho sentido separar la creación de subprocesos de la gestión de subprocesos en una aplicación.





El albacea es un le ayuda a crear y administrar hilos en una aplicación. los le ayuda en las siguientes tareas.

  • Creación de subprocesos: proporciona una variedad de métodos para la creación de subprocesos que ayudan a ejecutar sus aplicaciones al mismo tiempo.



  • Gestión de subprocesos: también gestiona el ciclo de vida de los subprocesos. No necesita preocuparse si el hilo está activo, ocupado o muerto antes de enviar la tarea para su ejecución.

  • Envío y ejecución de tareas: el marco de ejecución proporciona métodos para el envío de tareas en el grupo de subprocesos. También da el poder de decidir si el subproceso se ejecutará o no.

ExecutorService-ExecutorService en java -edureka

ExecutorService en el ejemplo de Java

Es una subinterfaz del marco ejecutor que agrega ciertas funcionalidades para administrar el ciclo de vida del hilo de una aplicación. También proporciona un método submit () que puede aceptar tanto ejecutables como invocables objetos.



En el siguiente ejemplo, crearemos un ExecutorService con un solo hilo y luego enviaremos la tarea para que se ejecute dentro del hilo.

import java.util.concurrent.ExecutorService import java.util.concurrent.Executors public class Ejemplo {public static void main (String [] args) {System.out.println ('Inside:' + Thread.currentThread (). getName ( )) System.out.println ('creando ExecutorService') ExecutorService ejecutorservice = Executors.newSingleThreadExecutor () System.out.println ('creando un ejecutable') Ejecutable ejecutable = () -> {System.out.println ('dentro: '+ Thread.currentThread (). GetName ())} System.out.println (' enviar la tarea especificada por el ejecutable al ejecutor servicio ') ejecutorservice.submit (ejecutable)}}
 Salida: Inside: main creando ExecutorService creando un ejecutable, envíe la tarea especificada por el ejecutable al ejecutorservice inside: pool-1-thread-1

Lo anterior muestra cómo podemos crear un ExecutorService y ejecutar una tarea dentro del ejecutor. Si una tarea se envía para su ejecución y el subproceso está actualmente ocupado ejecutando otra tarea, la tarea esperará en una cola hasta que el subproceso esté libre para ejecutarla.

Cuando ejecuta el programa anterior, el programa nunca se cerrará. Deberá cerrarlo explícitamente ya que el servicio ejecutor sigue escuchando nuevas tareas.

Implementaciones de Java ExecutorService

ExecutorService es muy similar a un grupo de subprocesos. De hecho, la implementación del ExecutorService en java.util.concurrent paquete es una implementación de threadpool. ExecutorService tiene las siguientes implementaciones en el paquete java.util.concurrent:

ThreadPoolExecutor

ThreadPoolExecutor ejecuta las tareas dadas utilizando uno de sus subprocesos agrupados internamente.

Creando un threadPoolExecutor

int corePoolSize = 5 int maxPoolSize = 10 long keepAliveTime = 5000 ExecutorService threadPoolExecutor = new threadPoolExecutor (corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, nuevo LinkedBlockingQueue ())

ScheduledThreadPoolExecutor

Java.util.concurrent.ScheduledThreadPoolExecutor es un ExecutorService que puede programar tareas para que se ejecuten después de un retraso o para que se ejecuten repetidamente con un intervalo fijo de tiempo entre cada ejecución.

Ejemplo

ScheduledExecutorService scheduledexecutorservice = Executors.newScheduledThreadPool (5) ScheduledFuture schedulefuture = scheduleExecutorService.schedule (new Callable () {public Object call () throws Exception {System.out.println ('ejecutado') return 'called'}}, 5, TimeUnit. SEGUNDOS)

Uso de ExecutorService

Hay algunas formas diferentes de delegar tareas a un ExecutorService.

  • ejecutar (ejecutable)

  • enviar (ejecutable)

  • invokeAny ()

  • invokeAll ()

Ejecutar ejecutable

Java ExecutorService execute (Runnable) toma un objeto java.lang.Runnable y lo ejecuta de forma asíncrona.

ExecutorService ejecutorService = Executors.newSingleThreadExecutor () ejecutorService.execute (new Runnable () {public void run () {System.out.println ('tarea asincrónica')}}) ExecutorService.shutdown ()

No hay forma de obtener el resultado de la ejecución Runnable, para eso tienes que usar el Callable.

Enviar Runnable

El método de envío Java ExecutorService (Runnable) toma una implementación Runnable y devuelve un objeto futuro. El objeto futuro se puede utilizar para comprobar si Runnable ha terminado de ejecutarse.

Future future = ejecutorService.submit (new Runnable () {public void run () {System.out.println (: asynchronous task ')}}) future.get () // devuelve nulo si la tarea se completa correctamente.

Enviar invocable

El método de envío (invocable) de Java ExecutorService es similar al envío (ejecutable) pero utiliza Java invocable en lugar de ejecutable.

Future future = ejecutorService.submit (new Callable () {public Object call () throws Exception {System.out.println ('Asynchronous invocable') return 'Callable Result'}}) System.out.println ('future.get ( ) = 'future.get ())
 Salida: Future.get invocable asíncrono = Resultado invocable

invokeAny ()

El método invokeAny () toma una colección de objetos invocables. Invocar este método no devuelve ningún futuro, pero devuelve el resultado de uno de los objetos invocables.

ExecutorService ejecutorService = Executors.newSingleThreadExecutor () Conjuntocallables = nuevo HashSet() callables.add (new Callable () {public String call () arroja Exception {return'task A '}}) callables.add (new Callable () {public String call () arroja Exception {return'task B'} }) callables.add (new Callable () {public String call () lanza Exception {return'task C '}}) String result = ejecutorService.invokeAny (callables) System.out.println (' resultado = '+ resultado) ejecutorService .apagar()

Cuando ejecuta el código anterior, el resultado cambia. Puede ser Tarea A, Tarea B, etc.

InvokeAll ()

El método invokeAll () invoca todos los objetos invocables pasados ​​como parámetros. Devuelve los objetos futuros que se pueden utilizar para obtener los resultados de la ejecución de cada invocable.

ExecutorService ejecutorService = Executors.newSingleThreadExecutor () Conjuntocallables = nuevo HashSet() callables.add (new Callable () {public String call () arroja Exception {return 'Task A'}}) callables.add (new Callable () {public String call () throws Exception {return 'Task B'} }) callables.add (new Callable () {public String call () lanza Exception {return 'Task C'}}) Listafutures = ejecutorService.invokeAll (invocables) para (Futuro futuro: futuros) {System.out.println ('future.get =' + future.get ())} ejecutorService.shutdown ()

Ejecutable vs Invocable

Las interfaces ejecutables y llamables son muy similares entre sí. La diferencia es visible en la declaración del interfaces. Ambas interfaces representan una tarea que puede ser ejecutada simultáneamente por un hilo o ExecutorService.

Declaración invocable:

public interface invocable {public object call () throws Exception}

Declaración ejecutable:

interfaz pública Ejecutable {public void run ()}

La principal diferencia entre los dos es que el método call () puede devolver un objeto de la llamada al método. Y el método call () puede lanzar un while run () método no puede.

código de ejemplo de Python de regresión logística

cancelar tarea

Puede cancelar la tarea enviada a ExecutorService simplemente llamando al método cancel en el futuro enviado cuando se envía la tarea.

future.cancel ()

ExecutorService Shutdown

Para evitar que los subprocesos se ejecuten incluso después de que se complete la ejecución, debe cerrar ExecutorService.

apagar()

Para terminar los hilos dentro de un ExecutorService, puede llamar al método shutdown ().

ejecutorService.shutdown ()

Esto nos lleva al final de este artículo donde hemos aprendido cómo podemos usar ExecutorService para ejecutar tareas en un hilo. Espero que tengas claro todo lo que se ha compartido contigo en este tutorial.

Si encuentra relevante este artículo sobre 'ExecutorService en Java', consulte el una empresa de aprendizaje en línea de confianza con una red de más de 250.000 alumnos satisfechos repartidos por todo el mundo.

Estamos aquí para ayudarlo en cada paso de su viaje y crear un plan de estudios diseñado para estudiantes y profesionales que desean ser desarrolladores de Java. El curso está diseñado para darle una ventaja en la programación de Java y capacitarlo para los conceptos básicos y avanzados de Java junto con varios me gusta Hibernar & .

Si encuentra alguna pregunta, no dude en hacer todas sus preguntas en la sección de comentarios de 'ExecutorService en Java' y nuestro equipo estará encantado de responder.