Anwendungen, die Parallelität und asynchrone Programmiermodelle verwenden, auf Liberty migrieren

Sie können Anwendungen, die Concurrency Utilities for Java™ EE, Asynchronous Beans, CommonJ-Zeitgeber und Arbeitsmanager verwenden, von WebSphere Application Server Traditional auf WebSphere Application Server Liberty migrieren.

Asynchronous Beans, CommonJ-Zeitgeber und Arbeitsmanager sind in Liberty nicht verfügbar. Bei einer Migration auf Liberty müssen Anwendungen auf das Programmiermodell von Concurrency Utilities for Java EE umgestellt werden. Weitere Informationen finden Sie unter Beispiel-API-Tasks, die Concurrency Utilities for Java EE implementieren.

Unterschiede bei der Konfiguration und beim Threading

WebSphere Application Server Traditional stellt eine Reihe von Konfigurationsoptionen für Concurrency Utilities for Java EE bereit, die sich auf das Thread-Pooling beziehen und in Liberty nicht verfügbar sind. Liberty verwendet einen einzigen allgemeinen Thread-Pool für alle Steuerprogramme für verwaltete und verwaltete geplante Tasks, die auch von Liberty-Komponenten genutzt werden. Auf diese Weise kann Liberty das Thread-Management optimieren. In WebSphere Application Server Traditional kann jeder Arbeitsmanager mit zwei Thread-Pools konfiguriert werden. Ein Thread-Pool ist für Tasks bestimmt, die zur möglichst schnellen Ausführung übergeben werden (Methoden submit/execute/invoke des Steuerprogramms für verwaltete Tasks), und hat eine konfigurierbare Arbeitsanforderungswarteschlange sowie Aktionen, die beim Überschreiten der Warteschlangenkapazität ausgeführt werden sollen. Der andere Thread-Pool ist für geplante Tasks (Methode "schedule" des Steuerprogramms für verwaltete geplante Tasks) bestimmt.

Wenn Sie vorhaben, Concurrency Utilities for Java EE mit separaten Thread-Pools in Liberty zu verwenden, stehen verschiedene Lösungen zur Verfügung, um ein Verhalten zu erzielen, das den in WebSphere Application Server Traditional verfügbaren Konfigurationsoptionen gleicht.

Java SE-Steuerprogramm mit einer Factory für verwaltete Threads (Managed-Thread-Factory) erstellen

Das Paket java.util.concurrent von Java SE bietet mehrere Möglichkeiten für die Erstellung von Thread-Pools als Steuerprogramme und Steuerprogramme für geplante Threads mit einer bestimmten Thread-Factory. Anstelle einer Factory für verwaltete Threads kann eine Factory für nicht verwaltete Threads bereitgestellt werden, woraufhin ein Thread-Pool generiert wird, in dem Tasks in verwalteten Threads ausgeführt werden. Anders als das Steuerprogramm für verwaltete Tasks und die Steuerprogramme für verwaltete geplante Tasks werden die von diesen Steuerprogrammen in den Pool gestellten verwalteten Threads mit dem Threadkontext ausgeführt, der bei der Suche der Factory für verwaltete Threads gültig war, und nicht mit dem Threadkontext, der bei der Übergabe oder Planung der Task gültig war. Der Thread behält diesen Threadkontext für seine gesamte Lebensdauer, was den Aufwand für den Wechsel des Threadkontexts reduziert.

Beispiel für die Ersetzung der maximalen Arbeitsthreadanzahl und die Konfiguration der Arbeitswarteschlange

int minThreads = 1;
int maxThreads = 2;
int workRequestQueueSize = 3;
RejectedExecutionHandler workRequestQueueFullAction =
    new ThreadPoolExecutor.AbortPolicy(); 
ManagedThreadFactory threadFactory =
    (ManagedThreadFactory) new InitialContext().lookup(
        "java:comp/DefaultManagedThreadFactory");
ExecutorService executor = new ThreadPoolExecutor(
    minThreads, // similar, but not exact match for coreSize
    maxThreads, keepAliveTime, keepAliveTimeUnit,
    new ArrayBlockingQueue<Runnable>(workRequestQueueSize),
    threadFactory,
    workRequestQueueFullAction);
Callable<Integer> task = new MyTask();
Future<Integer> future = executor.submit(task);
int result = future.get();

Beispiel für die Ersetzung der maximalen Alarmthreadanzahl

int maxAlarms = 2;
ManagedThreadFactory threadFactory =
    (ManagedThreadFactory) new InitialContext().lookup(
        "java:comp/DefaultManagedThreadFactory");
ScheduledExecutorService executor =
    Executors.newScheduledThreadPool(maxAlarms, threadFactory);
Callable<Integer> task = new MyTask();
ScheduledFuture<Integer> future = executor.schedule(
    task, 50, TimeUnit.SECONDS);
int result = future.get();

Arbeitszeitlimit anwenden

Sie können in WebSphere Application Server Traditional ein Arbeitszeitlimit konfigurieren, das für Tasks gilt, die zur möglichst schnellen Ausführung übergeben werden (Methoden submit/execute/invoke). Wenn das zulässige Arbeitszeitlimit bei der Ausführung einer Task überschritten wird, wird versucht, die Task durch Unterbrechung abzubrechen. In Liberty wird das Arbeitszeitlimit nicht als Konfigurationsoption angeboten, aber ein ähnliches Verhalten kann durch Übergabe der Task mit einem Listener für verwaltete Tasks übergeben werden, der als Antwort auf die taskStarting-Benachrichtigung eine Task zum Abbrechen der künftigen Ausführung der Task (Future) plant. Wenn wie im vorherigen Beispiel ein Steuerprogramm für den Thread-Pool verwendet wird, in dem kein Listener für verwaltete Tasks verfügbar ist, ist es alternativ möglich, die Methode beforeExecute des Steuerprogramms des Thread-Pools zu überschreiben, um eine Task für die Unterbrechung des Ausführungsthreads zu planen.

Beispiel für die Ersetzung des Arbeitszeitlimits

ManagedExecutorService executor = 
    (ManagedExecutorService) new InitialContext().lookup(
        "java:comp/DefaultManagedExecutorService");
Callable<Long> slowTask = new SlowTask();
slowTask = ManagedExecutors.managedTask(
           slowTask, new WorkTimeout(5, TimeUnit.SECONDS));
Future<Long> future = executor.submit(slowTask);
try  {
    long result = future.get(1, TimeUnit.MINUTES);
    // Task erfolgreich...
} catch (CancellationException x) {
    // Task abgebrochen, möglicherweise wegen einer Zeitlimitüberschreitung
}

public class WorkTimeout implements ManagedTaskListener {
    private final long timeout;
    private final TimeUnit unit;

    public WorkTimeout(long timeout, TimeUnit unit) {
        this.timeout = timeout;
        this.unit = unit;
    }

    public void taskSubmitted(Future<?> future,
        ManagedExecutorService executor, Object task) {}

    public void taskStarting(final Future<?> future,
        ManagedExecutorService executor, Object task) {
        try  {
            ScheduledExecutorService scheduledExecutor =
                (ScheduledExecutorService) new InitialContext().lookup(
                    "java:comp/DefaultManagedScheduledExecutorService");
            scheduledExecutor.schedule(new Runnable() {
                @Override
                public void run() {
                    if (!future.isDone())
                        future.cancel(true);
                }
            }, timeout, unit);
        } catch (NamingException x) {
            x.printStackTrace(System.out);
        }
    }

    public void taskAborted(Future<?> future, ManagedExecutorService executor, Object task, Throwable x) {}

    public void taskDone(Future<?> future, ManagedExecutorService executor, Object task, Throwable x) {}
}

Symbol das den Typ des Artikels anzeigt. Referenzartikel



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