1

我有一个以某种方法启动的 WM:

public void someMethod(Params pararms){
     WorkManager wm = (WorkManager) ic.lookup(CONTROL_WORK_MANAGER);
     ArrayList<WorkItem> workItems = Lists.newArrayList();
     List<Work> works = getSomeWorks();
     for (Work work : works) {
         workItems.add(wm.startWork(work));
          }
     //after all works have been started, I just wait for them to be finished using join method:
     wm.join(workItems, WorkManager.JOIN_AND, (int) WorkManager.INDEFINITE);

    // "other code"
    }

someMethod()由不同的线程调用,问题wm.join()不在于只等待给定的工作完成,而是等待所有线程启动的所有工作。最终"other code"在应用程序中的每一项工作完成时执行。

它应该是这样吗?如果是这样,我可以修复它,所以每个wm.join()人都只等待“它的”工作完成吗?

WAS 版本是 8.5.5.11

谢谢!

4

1 回答 1

3

根据 WorkManager 的记录行为,它应该等待提供的列表中的项目。

https://www.ibm.com/support/knowledgecenter/SS7K4U_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/com/ibm/websphere/asynchbeans/WorkManager.html

具体来说,JOIN_AND 被定义为“这个常量用于连接方法的 ANDOR 参数,表示连接方法应该等待列表中的所有工作项完成。”

您描述的观察到的行为听起来像一个错误,我将确认是否可以重现相同的行为。

我还要提到,如果这种行为确实有问题并且您需要替换它,一种方法是使用注册一个递减 java.util.concurrent.CountDownLatch 的 WorkListener,您可以等待从您的提交者线程。

final CountDownLatch latch = new CountDownLatch(works.size());
WorkListener listener = new WorkListener() {
    public void workAccepted(WorkEvent we) {}
    public void workStarted(WorkEvent we) {}
    public void workCompleted(WorkEvent we) {
        latch.countDown();
    }
    public void workRejected(WorkEvent we) {
        latch.countDown();
    }
};
for (Work work : works) {
    workItems.add(wm.startWork(work, WorkManager.INDEFINITE, listener));
}
latch.await();

或者,如果您能够迁移到 WAS v9 以支持 Java EE 7,那么听起来您真正想要的是 javax.enterprise.concurrent.ManagedExecutorService.invokeAll() ,它内置了组合的提交和等待行为。

于 2017-03-23T13:33:11.497 回答