Как портировать WaitForMultipleObjects на Java?

У меня есть код на C++ для Windows, и я собираюсь перенести его на Java. Но, к сожалению, это не так просто, как я думал. Может ли кто-нибудь помочь мне, пожалуйста?

Пожалуйста, взгляните на алгоритм:

HANDLE hExitEvent;
HANDLE hDataAvailabeEvent;

while(true)
{
  WaitForMultipleObjects();
  if (hExitEvent is set)
    break;
  if (hDataAvailabeEvent)
  {
    process chunk of data;
    if (all data processed)
      ResetEvent(hDataAvailabeEvent);
  }
}

hDataAvailabeEvent можно установить из разных потоков. Если все данные обработаны, то событие сбрасывается и при вызове WaitForMultipleObjects поток приостанавливается, пока не поступят новые данные или не наступит время для выхода из потока.

Я уже видел вопрос Waitformultipleobjects в Java, но он не подходит для моей ситуации, потому что я не могу обработать все новые данные за 1 итерацию цикла, а обработка распространяется на несколько итераций.

Заранее спасибо!


person nbulba    schedule 03.11.2009    source источник


Ответы (2)


Простое решение, которое, казалось бы, удовлетворит ваши потребности, выглядит примерно так:

class DataProcessor implements Runnable {
    private final ExecutorService executor = 
        Executors.newSingleThreadedExecutor();

    public void stop { executor.shutdown(); }

    public void process(final Data data){
        executor.execute(new Runnable(){
            public void run(){
                // process data
            }
        });
    }

}

У вас действительно нет никаких событий, но это работает примерно так же. Хотите добавить данные в очередь обработки? Позвоните process, и executor обработает ваш Data, когда он завершит все предыдущие задачи в очереди. Выключение? Вызовите stop, и executor завершит обработку всего в очереди, но больше не будет принимать работу. (Если вам нужен более резкий конец, используйте ExecutorService.shutdownNow).

person gustafc    schedule 03.11.2009
comment
Спасибо gustafc! Я предполагаю, что это пул потоков. Как один из способов реализации это может быть, но подскажите пожалуйста: будет оператор executor.shutdown(); закончить метод запуска изящно? Могу ли я явно указать объектам, используемым при запуске, останавливаться в случае executor.shutdown()? Возможно, внутри прогона возникнет какое-то исключение? - person nbulba; 03.11.2009
comment
Нет, run всегда закончит изящно. Java на самом деле не делает резких остановок потока. Как говорится в документах для shutdown, отправленные задачи выполняются, но новые задачи не принимаются — новые рабочие элементы не принимаются, но поток будет продолжать работать до тех пор, пока рабочая очередь не станет пустой. Что касается shutdownNow, то он позволяет завершить выполняемый в данный момент Runnable, но не начинает работу над какими-либо новыми элементами. - person gustafc; 03.11.2009
comment
Если вы хотите иметь возможность прервать текущую выполняемую задачу, когда ваш процессор выключается, вы можете просто сделать что-то вроде if (executor.isShutdown()) return; в соответствующих местах в run . - person gustafc; 03.11.2009

WaitForMultipleObjects — это функция Windows API. Лично я бы реализовал это с помощью простых событий (вместо вызова ResetEvent ваши потоки запускают какое-то событие и регистрируют один рабочий поток для прослушивания этих событий).

person Max Lybbert    schedule 03.11.2009