将使用并行和异步编程模型的应用程序迁移到 Liberty
您可以将使用 Concurrency Utilities for Java™ EE、异步 Bean 和 CommonJ Timer and Work Manager 的应用程序从 WebSphere® Application Server 传统版迁移到 WebSphere Application Server Liberty。
异步 Bean 和 CommonJ Timer and Work Manager 在 Liberty 中不可用。迁移到 Liberty 时,应用程序必须切换为 Concurrency Utilities for Java EE 编程模型。有关更多信息,请参阅实现 Concurrency Utilities for Java EE 的 API 任务示例。
配置和线程技术方面的差别
WebSphere Application Server 传统版 为 Concurrency Utilities for Java EE 提供了许多与线程池相关的配置选项,这些选项在 Liberty 中以不同的方式配置,或者不可用。Liberty 具有单个公共线程池,它由所有受管执行程序和受管调度执行程序共享,而这些执行程序也由 Liberty 组件共享。这允许 Liberty 优化线程管理。在 WebSphere Application Server 传统版 中,可以为每个工作管理器配置两个线程池。其中一个线程池用于提交为尽快运行的任务(受管执行程序的提交/执行/调用方法),并且具有可配置的工作请求队列,以及在超过队列容量时要执行的操作。另一个线程池用于调度的任务(受管调度执行程序的调度方法)。
如果您打算在 Liberty 中将 Concurrency Utilities for Java EE 与不同线程池配合使用,那么可采用各种方法,实现类似于 WebSphere Application Server 传统版中的配置选项的行为。
![[17.0.0.4 and later]](../ng_v17004plus.gif)
使用并行策略配置
使用 concurrencyPolicy 元素可在 Liberty 中再现 WebSphere Application Server 传统版中的某些行为。下表列出 concurrencyPolicy 元素的可用配置选项,以及此元素与 WebSphere Application Server 传统版的对比。concurrencyPolicy 配置不适用于调度的任务。
Liberty 受管执行程序 concurrencyPolicy | WebSphere Application Server 传统版工作管理器和受管执行程序 |
---|---|
max | 最大线程数 |
maxQueueSize | 工作请求队列大小 |
maxWaitForEnqueue | 工作请求队列已满操作 = WAIT |
runIfQueueFull = false | 工作请求队列已满操作 = FAIL |
startTimeout | 启动超时 |
longRunningPolicyRef + longrunning 提示 | 守护程序工作 |
expedite 元素等于在 Liberty 全局线程池上加速的目标最小线程数(而不是固定的最小线程数)。
基于受管线程工厂构造 Java SE 执行程序
Java SE 的 java.util.concurrent 包提供了多种方法,基于特定的线程工厂构造线程池作为执行程序和调度执行程序。可以提供受管线程工厂来取代非受管线程工厂,这将生成一个通过受管线程运行任务的线程池。与受管执行程序和受管调度执行程序不同,由这些执行程序合用的受管线程从查找受管线程工厂时开始(而不是从提交或调度任务时开始),就以线程上下文来运行。线程上下文在线程生存期内也保留在受管线程中,这可减少线程上下文切换开销。
![[17.0.0.4 and later]](../ng_v17004plus.gif)
最大工作线程数与工作队列配置的替换示例
<managedExecutorService jndiName="concurrent/execSvc">
<concurrencyPolicy max="2" maxQueueSize="3" runIfQueueFull="false" maxWaitForEnqueue="0"/>
</managedExecutorService>
最大警报线程数的替换示例
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();
![[17.0.0.4 and later]](../ng_v17004plus.gif)
应用启动超时
<managedExecutorService jndiName="concurrent/execSvc">
<concurrencyPolicy startTimeout="1m"/>
</managedExecutorService>
应用工作超时
使用 WebSphere Application Server 传统版可配置工作超时,该超时将应用于您提交为尽快运行的任务(提交/执行/调用方法)。如果任务运行时间超过分配的工作超时,那么程序会尝试通过中断该任务将其取消。Liberty 没有配置选项形式的工作超时,但您可以使用受管任务侦听器来提交任务,以实现类似的行为。为响应 taskStarting 通知,受管任务侦听器会调度一个任务以取消 Future 方法。或者,当您使用没有受管任务侦听器的线程池执行程序时,可以覆盖线程池执行程序 beforeExecute 方法,以调度用于中断执行线程的任务。
工作超时的替换示例
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 successful...
} catch (CancellationException x) {
// task was canceled, possibly due to timeout
}
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) {}
}
![[17.0.0.4 and later]](../ng_v17004plus.gif)
守护程序工作的示例
配置:
<concurrencyPolicy id="longRunning" max="2"/>
<managedExecutorService jndiName="concurrent/execSvc" longRunningPolicyRef="longRunning" />
应用程序代码:
ManagedExecutorService executor =
(ManagedExecutorService) new InitialContext().lookup(
"concurrent/execSvc");
Map<String, String> props = Collections.singletonMap(ManagedTask.LONGRUNNING_HINT,
Boolean.TRUE.toString());
Callable<Long> slowTask = ManagedExecutors.managedTask(new SlowTask(), props, null);
Future<Long> future = executor.submit(slowTask);