Java Concurrency: уведомления о потоках - PullRequest
1 голос
/ 21 ноября 2011

У меня проблема с параллелизмом Java, она выглядит следующим образом: существует сервлет ( serv1 ), который хранит объекты (представляющие сообщения) в базе данных. Существует также поток ( t1 ), который ищет (в базе данных) неотправленные сообщения и доставляет их. t1 запускается каждые 5 минут, поэтому в целях эффективности serv1 уведомляет t1 каждый раз, когда сохраняет сообщение.

Вопрос в том, как процесс уведомлений будет вести себя по сильно согласованному сценарию, когда serv1 получает чрезвычайно большое количество запросов и, таким образом, t1 получает столько уведомлений, что имитирует " while (true) " ?.

Еще один вопрос: как будет вести себя процесс уведомления, если serv1 хочет уведомить t1 , но t1 уже проснулся / работает?

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

Ответы [ 3 ]

2 голосов
/ 22 ноября 2011

Не думаю, что это проблема @ Уилмер. Я подозреваю, что само уведомление является относительно дешевым по сравнению со стоимостью использования и обработки ваших сообщений. Если вы потребляете много времени, то удаление сообщений не поможет процессу, и вам придется каким-то образом заблокировать ваш поток serv1 или разгрузить задания для запуска позже.

С точки зрения уведомлений, если никто не ждет, то notify() фактически является запретом. Вот почему важно проверить, есть ли что-то, что нужно обработать до ожидания сигнала - все в синхронизированном блоке. Рекомендуется также зацикливаться на ожидании и проверять снова, когда мы получим уведомление. Смотрите это состояние гонки .

В общем, это очень распространенная практика, которая используется практически во всех моделях потоков производителей / потребителей , которые я видел. Альтернатива не обрабатывать изменения трафика прямоугольной формы. Либо ваш потребитель (t1) ждет слишком долго и буферы заполняются, либо он слишком много вращается и слишком много потребляет процессор, проверяя базу данных.

Еще одна вещь, которую следует учитывать, - это не использовать базу данных, а поместить объекты в BlockingQueue для t1 для непосредственного использования. Если вам необходимо сохранить их в базе данных, поместите идентификаторы объектов в очередь для использования t1. Потоку все равно нужно будет опрашивать базу данных при запуске, но вы сохраните опросы позже в процессе.

1 голос
/ 21 ноября 2011

Почему вы вообще уведомляете t1?Почему T1 не выполняет 5-минутный цикл запроса к базе данных и не обрабатывает все ожидающие сообщения?Тогда вам вообще не нужно уведомление, вы просто используете базу данных.

0 голосов
/ 22 ноября 2011

Чтобы правильно использовать Object o = new Object(); o.notify(), это необходимо сделать после получения монитора этого объекта (становясь его владельцем; AKA synchronize на нем).Кроме того, пробужденный поток, ожидающий этот монитор, должен будет еще раз дождаться, когда уведомляющий поток освободит этот монитор и попытается его получить.Только тогда он продолжит обработку.

Таким образом, когда пробудится t1 , он фактически будет сражаться со всеми другими потоками serv1 за то, что стал владельцем монитора.Он может получить монитор, таким образом останавливая все потоки serv1 (не хорошо).Он может постоянно проигрывать потокам serv1 и не обрабатывать накапливающиеся сообщения в базе данных (я думаю, это так же плохо).

Что вы должны сделать, это позволить производителям ( serv1 threads) работает асинхронно с потребителем ( t1 ). t1 должен продолжать выполняться каждые X минут (или секунд) и обрабатывать все сообщения в целом.Другой вариант, если вы хотите поддерживать низкую активность потока: настройте несколько потребительских потоков ( t1 , t2 , t3 ... и т. Д.).Вы можете использовать Executors.newFixedThreadPool(int nThreads, ThreadFactory threadFactory) для этой цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...