Desarrollo de tareas para ejecutar código en paralelo

Para realizar operaciones en paralelo, puede derivar el código en una tarea Callable o Runnable y, a continuación, enviarlo o planificarlo en un ejecutor gestionado.

Antes de empezar

De manera opcional, el administrador puede utilizar la consola administrativa para configurar al menos un gestor de trabajo o cambiar los valores del gestor de trabajo predeterminado.

Acerca de esta tarea

Para ejecutar el código en paralelo, derive el código en una tarea Callable o Runnable y, a continuación, envíelo o planifíquelo en un ejecutor gestionado.

Procedimiento

  1. Implemente una tarea Callable o Runnable.

    Una tarea implementa la interfaz java.util.concurrent.Callable o la interfaz de java.lang.Runnable. Por ejemplo, puede crear una tarea que se suscriba dinámicamente a un tema y cualquier componente.

    class SampleTask implements Callable<Object>
    {
       Set<MessageListener> listeners =      
          Collections.newSetFromMap(new ConcurrentHashMap<MessageListener, Boolean>();
       Topic targetTopic;
       TopicConnectionFactory tcf;
    
       public SampleWork(TopicConnectionFactory tcf, Topic targetTopic)
       {
          this.targetTopic = targetTopic;
          this.tcf = tcf;
       }
    
       public void addMessageListener(MessageListener listener) 
       {
          listeners.add(listener);
       }
    
       public Object call() throws JMSException
       {
          // configurar JMS stuff.TopicConnection
          tc = tcf.createConnection();
          try
          {
             TopicSession sess = tc.createSession(false, Session.AUTOACK);
             tc.start();
             while( !Thread.currentThread().isInterrupted() )
             {
                // bloqueo de hasta 5 segundos.
                Message msg = sess.receiveMessage(5000);
                if(msg != null)
                   for (MessageListener listener : listeners)
                      listener.onMessage(msg);
             }
             tc.close();
          }
          finally
          {
             if (tc != null) tc.close();
          }
       }
    }

    Como resultado, todo componente puede añadir un escucha de mensajes a petición, lo que permite a los componentes suscribirse a un tema de forma más escalable que si se da a cada suscriptor del cliente su propia hebra.

  2. Determine el número de gestores de trabajo que necesita este componente de aplicación.
  3. Busque el gestor o los gestores de trabajo utilizando el ejecutor gestionado, la fábrica de hebras, la referencia de entorno de recursos del servicio de contexto o la referencia de recursos del gestor de trabajo (o nombre lógico) en el espacio de nombres java:comp. (Para obtener más información sobre las referencias de entorno de recursos y las referencias de recursos, consulte el tema Referencias).
    InitialContext ic = new InitialContext();
    ManagedExecutorService executor = (ManagedExecutorService)ic.lookup("java:comp/env/concurrent/myWorkManager");
    La referencia de entorno de recursos para el ejecutor gestionado (en este caso, concurrent/myWorkManager) debe declararse como una referencia de entorno de recursos en el descriptor de despliegue de la aplicación o una anotación @Resource.
  4. Llame al método ManagedExecutorService.submit() utilizando la instancia de tarea Callable o Runnable como parámetro. Por ejemplo:
    Callable<Boolean> task = new MyTask(...);
    Future<Boolean> future = executor.submit(task);

    Future es un manejador que proporciona un enlace desde el componente a la tarea enviada.

  5. Opcional: Si el componente de aplicación necesita esperar a que una o varias de sus tareas finalice, llame al método Future.get(). Por ejemplo:
    Future<String> futureA = executor.submit(taskA);
    Future<String> futureB = executor.submit(taskB);
    futureA.get(5, TimeUnit.SECONDS);
    futureB.get(5, TimeUnit.SECONDS);

    De manera alternativa, utilice el método invokeAll() para enviar varias tareas y esperar a que todas finalicen. Por ejemplo:

    tasks = Arrays.asList(taskA, taskB);
    futures = executor.invokeAll(tasks, 5, TimeUnit.SECONDS);
        // podemos comprobar future.isDone para ver cuál, en el caso de que exista alguna, ha finalizado.

    Este método utiliza una colección de tareas a las que el componente desea esperar para que finalicen todos los objetos de trabajo. También puede especificar un valor de tiempo de espera.

  6. Utilice el método Future.cancel(true) para intentar interrumpir la tarea.

    Implemente la tarea para responder a la interrupción inmediatamente o intente detener la ejecución lo antes posible.


Icon that indicates the type of topic Task topic



Timestamp icon Last updated: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tasb_devwkobj
File name: tasb_devwkobj.html