Arbeitsobjekte für die parallele Codeausführung entwickeln

Sie können Operationen parallel ausführen, indem Sie den Code in ein aufrufbares bzw. ausführbares Objekt einschließen und dann an ein verwaltetes Steuerprogramm übergeben bzw. den Code im Steuerprogramm planen.

Vorbereitende Schritte

Optional kann Ihr Administrator die Administrationskonsole verwenden, um mindestens einen Arbeitsmanager zu konfigurieren oder die Einstellungen des Standardarbeitsmanagers zu ändern.

Informationen zu diesem Vorgang

Wenn Sie Code parallel ausführen möchten, schließen Sie den Code in ein aufrufbares bzw. ausführbares Objekt ein und übergeben Sie ihn an ein verwaltetes Steuerprogramm oder planen Sie den Code in diesem Steuerprogramm.

Vorgehensweise

  1. Implementieren Sie eine aufrufbare bzw. ausführbare Task.

    Eine Task implementiert die Schnittstelle java.util.concurrent.Callable oder java.lang.Runnable. Sie können beispielsweise eine Task erstellen, die ein Topic dynamisch subskribiert, und jede Komponente kann bei Bedarf einen Nachrichtenlistener hinzufügen.

    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
       {
          // Konfiguration von JMS stuff.TopicConnection
          tc = tcf.createConnection();
          try 
          {
             		TopicSession sess = tc.createSession(false, Session.AUTOACK);
             		tc.start();
             while( !Thread.currentThread().isInterrupted() )
             {
                			// Bis zu 5 Sekunden lang blockieren.
                			Message msg = sess.receiveMessage(5000);
                			if(msg != null)
                   for (MessageListener listener : listeners)
                      listener.onMessage(msg);
             }
             		tc.close();
          }
          finally
          {
             if (tc != null) tc.close();
          }
       }
    }

    Als Ergebnis dieser Codeausführung kann jede Komponente bei Bedarf einen Nachrichtenlistener hinzufügen, so dass die Komponenten ein Topic auf flexiblere Art und Weise subskribieren können, als wenn sie lediglich jedem Clientsubskribenten einen eigenen Thread zuteilen würden.

  2. Legen Sie die Anzahl der Arbeitsmanager fest, die von dieser Anwendungskomponente benötigt werden.
  3. Suchen Sie den oder die Arbeitsmanager im Namespace java:comp, indem Sie die Ressourcenumgebungsreferenz für das verwaltete Steuerprogramm, die Thread-Factory oder den Kontextservice bzw. die Ressourcenreferenz für den Arbeitsmanager (oder dessen logischen Namen) verwenden. (Weitere Informationen zu Ressourcenumgebungsreferenzen und Ressourcenreferenzen finden Sie im Artikel "Referenzen".)
    InitialContext ic = new InitialContext();
    ManagedExecutorService executor = (ManagedExecutorService)ic.lookup("java:comp/env/concurrent/myWorkManager");
    Die Ressourcenumgebungsreferenz für das verwaltete Steuerprogramm (in diesem Fall concurrent/myWorkManager) muss als Ressourcenumgebungsreferenz im Anwendungsimplementierungsdeskriptor oder als @Resource-Annotation deklariert sein.
  4. Rufen Sie die Methode ManagedExecutorService.submit() auf, indem Sie die aufrufbare bzw. ausführbare Taskinstanz als Parameter verwenden. Beispiel:
    Callable<Boolean> task = new MyTask(...);
    Future<Boolean> future = executor.submit(task);

    "Future" ist eine Kennung, die einen Link von der Komponente zu der übergebenen Task bereitstellt.

  5. Optional: Falls die Anwendungskomponente auf die Beendigung einer oder mehrerer Tasks warten muss, rufen Sie die Methode Future.get() auf. Beispiel:
    Future<String> futureA = executor.submit(taskA);
    Future<String> futureB = executor.submit(taskB);
    futureA.get(5, TimeUnit.SECONDS);
    futureB.get(5, TimeUnit.SECONDS);

    Alternativ dazu können Sie die Methode invokeAll() verwenden, um mehrere Tasks zu übergeben und auf deren Beendigung zu warten. Beispiel:

    tasks = Arrays.asList(taskA, taskB);
    futures = executor.invokeAll(tasks, 5, TimeUnit.SECONDS);
        // future.isDone() kann geprüft werden, um festzustellen, welches Objekt gegebenenfalls beendet wird.

    Diese Methode verwendet eine Sammlung von Tasks, auf deren Beendigung die Komponente für alle abzuschließenden Arbeitsobjekte warten möchte. Sie können auch einen Zeitlimitwert festlegen.

  6. Verwenden Sie die Methode Future.cancel(true), um die Task zu unterbrechen.

    Implementieren Sie die Task, um unmittelbar auf die Unterbrechung zu reagieren oder um zu versuchen, die Ausführung schnellstmöglich zu stoppen.


Symbol, das den Typ des Artikels anzeigt. Taskartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tasb_devwkobj
Dateiname:tasb_devwkobj.html