Соединение Websphere WorkManager для многих потоков

У меня есть один 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.

Благодарю вас!


person SergeiK    schedule 23.03.2017    source источник


Ответы (1)


Согласно задокументированному поведению 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 метода соединения, чтобы указать, что метод соединения должен ожидать завершения всех рабочих элементов в списке».

Наблюдаемое поведение, которое вы описываете, звучит как ошибка, и я постараюсь подтвердить, смогу ли я воспроизвести то же самое.

Я также упомяну, что в случае, если это поведение действительно ошибочно и вам нужно его заменить, один из подходов заключается в регистрации WorkListener, который уменьшает java.util.concurrent.CountDownLatch, который вы можете await из вашей ветки отправителя.

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(), в котором встроено комбинированное поведение отправки и ожидания.

person njr    schedule 23.03.2017