2016-12-06 3 views
1

У меня есть программа, для которой необходим цикл бесконечности. Причиной этого является то, что у меня есть потребитель SQS, который будет выделять поток для каждого получаемого сообщения, и именно здесь большая часть моей логики. К сожалению, потребитель SQS внутренне работает в другом потоке, который я не контролирую, поскольку лучшей реализацией было бы запустить его в основном потоке.Каков наилучший способ создания бесконечного цикла в java?

Мне нужен способ остановить запуск программы, пока потребитель жив, в настоящее время я использую цикл while со сном Thread, но я помню что-то об этом не очень хорошее решение.

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

Update: Программа не предназначена, чтобы остановить когда-либо, SQSConsumer раскрутит 10 потоков, которые тянут сообщения от службы, я хочу, чтобы продолжать делать это до тех пор, я не заставить программу выхода путем установки потребителя. isRunning() в false или путем принудительного завершения программы с помощью Ctrl + c.

Пример:

SQSConsumer consumer = new SQSConsumer((event) -> { 
    callSomeLogicHere(event); 
}); 
while (consumer.isRunning()) { 
    Thread.sleep(100); 
} 
+4

Цель многопоточности потерпела поражение – GurV

+0

Можете ли вы дать более подробную информацию о своем классе SQSConsumer? – assylias

ответ

3

Используйте CountdownLatch:

  • Создать окончательный (или фактически окончательный) переменную перед вызовом потребителя:

    CountdownLatch latch = new CountdownLatch(1); 
    
  • В вашем лямбда , объедините вызов другой логике с помощью try/finally:

    try { 
        callSomeOtherLogic(); 
    } finally { 
        latch.countDown(); 
    } 
    
  • Затем, когда вы хотите ждать потребитель закончить, ждать защелки:

    latch.await(); 
    

Обратите внимание, что это не "лучший" способ сделать это, поскольку редко существует объективно лучший подход в целом; есть только лучшее в отношении конкретного приложения.

С учетом этого, это лучше, чем опрос, потому что вам не нужно продолжать проверять, завершен ли другой поток. Если вы проверяете завершение каждые 100 мс, а другой поток занимает не менее 10 минут для завершения, это очень много пустых проверок; вы могли бы использовать свой процессор, чтобы делать более ценную работу. Вы можете увеличить время ожидания, чтобы делать меньшее количество проверок реже, но затем увеличивайте ожидаемое дополнительное время ожидания между завершением процесса и его обнаружением (ожидаемое дополнительное ожидание составляет половину продолжительности сна).

Следует также отметить, что это предполагает, что завершение лямбда указывает на завершение потребителя. Это может быть и не так:

  • Этот подход предполагает, что лямбда выполняется ровно один раз. Это предположение может быть неверным, например, если lambda выполняется несколько раз или, может быть, никогда.
  • Даже если он выполняется только один раз, потребитель может сделать больше работы после; вам может потребоваться немного дольше (или даже опрос для завершения) после того, как защелка будет подсчитана.

Короче говоря, это не обязательно лучший или даже правильный подход для этого случая. Тем не менее, существует целый пакет параллельных утилит - java.util.concurrent - обеспечивает лучшую функциональность, чем просто опрос, некоторые из которых могут быть подходящими в этом случае.

+0

Почему это лучший способ? – abbath

+0

Я обновил свое первое сообщение с дополнительной информацией. Я не думаю, что это сработает, так как функция лямбда называется «бесконечным временем», – Androme

Смежные вопросы