Производитель-потребитель - необходимо обрабатывать очередь, когда очередь заполнена или по прошествии определенного времени.

Я использую Java в качестве интерфейса программирования. Вот мой рабочий поток. У меня есть производитель, у которого есть имя файла с путем, и он добавляет его в очередь. А затем потребитель, который его потребляет. После исключения из очереди я добавляю его в arraylist, а затем проверяю, достиг ли он значения x. Если да, то буду обрабатывать. Все идет нормально. Но проблема в том, что у меня есть один файл в этом списке. Он не обрабатывается, пока список файлов не достигнет размера x. Я хотел, чтобы истек какой-то таймер, и через y минут я хотел обработать список файлов, если он не пуст. Как мне этого добиться? Я знаю о задаче таймера, запланированном исполнителе, но он запускает поток после запланированного времени, что не в моем случае. Я могу предоставить более подробную информацию, если вам нужно. Пожалуйста, дайте мне знать, если мой дизайн неправильный, и спасибо за помощь.


person AnswerSeeker    schedule 13.08.2017    source источник
comment
Если вы голосуете против вопроса, пожалуйста, укажите причину. Мне действительно интересно знать, так как не все все знают.   -  person AnswerSeeker    schedule 13.08.2017


Ответы (1)


Каждый раз, когда вы пытаетесь исключить файлы из очереди, проверяйте отметку времени, которую вы установили при использовании последнего файла. Если эта метка времени больше вашего порогового времени и у вас есть n файлов в очереди (где n ‹ x) — используйте файлы, даже если они не достигли x.

псевдокод:

timestamp <= now
every k milliseconds:
   check the number of files n in queue:
       if n >= x:
           consume the files
           update timestamp (to "now")
       else if (now - timestamp > time-threshold):
           consume the files
           update timestamp (to "now")
person Nir Alfasi    schedule 13.08.2017
comment
Я попробую это. Есть ли решение в java, похожее на событие VC++, где запускается OnTimer() - person AnswerSeeker; 13.08.2017
comment
@AnswerSeeker что за событие? мне кажется, что вы хотите спать 1/2/3 секунды и проверять очередь в цикле - вам также не нужны потоки - основной поток может это сделать! - person Nir Alfasi; 13.08.2017
comment
Что я хотел сделать, чтобы обработать все файлы в очереди, если истекло фиксированное время или если очередь заполнена. Событие VC++ я где-то читал, но могу ошибаться. Пожалуйста, игнорируйте это - person AnswerSeeker; 13.08.2017
comment
Я думаю, что описанный выше подход ^^^ легко реализовать. Кроме того, если вы хотите, чтобы очередь обрабатывалась немедленно (без сна), вы можете обернуть очередь своим самодельным классом, который проверяет размер при вставке, и, если емкость достигнута, запускает потребление - person Nir Alfasi; 13.08.2017
comment
Я попробовал этот подход и, кажется, не подходит. Я использую LinkedBlockingQueue, и когда я вызываю take(), кажется, что он ждет, когда очередь пуста. Удаление из очереди добавляется к List‹String› и остается необработанным, так как блокирующая очередь take() просто ждет. Мой первоначальный подход состоял в том, чтобы исключить его из очереди и добавить в список. Как только список достигает максимальной емкости, список файлов обрабатывается. Не хватает только таймера, который по истечении срока действия обрабатывает список файлов. - person AnswerSeeker; 15.08.2017
comment
Я создал ScheduledExecutorService, который запускается каждую минуту и ​​вызывает мою пользовательскую функцию processData() для обработки списка файлов. Я синхронизировал список файлов, чтобы сделать его потокобезопасным. Большое спасибо за Вашу помощь. Я все еще принял ваш ответ, так как этот подход работает, если вы не используете очередь блокировки. - person AnswerSeeker; 15.08.2017
comment
@AnswerSeeker, если вы не хотите блокировать, вместо take() вы можете использовать poll - person Nir Alfasi; 15.08.2017