Arhn - архитектура программирования

Очередь отправки электронной почты Java - фиксированное количество потоков, отправляющих столько сообщений, сколько доступно

Я пишу приложение для обработки сообщений (электронной почты), для которого хочу иметь исходящую очередь. Я разработал это таким образом, чтобы иметь одноэлементный класс очереди, ThreadedQueueSender, поддерживаемый службой Executor и BlockingQueue. Кроме того, пул потоков объектов javax.mail.Transport используется для получения и освобождения соединений с исходящим SMTP-сервером.

Этот класс предоставляет метод add(MimeMessage), который добавляет сообщения в рабочую очередь (BlockingQueue).

При создании экземпляра класса ExecutorService инициализируется ThreadPoolExecutor с фиксированным количеством потоков, скажем, 5. Метод run() каждого потока находится в бесконечном цикле, который завершается только при обнаружении прерывания (когда вызывается ExecutorService.shutdownNow()).

Этот метод запуска использует BlockingQueue.poll() для получения сообщений из рабочей очереди до тех пор, пока больше не будет доступно без блокировки, затем запрашивает объект Transport из пула соединений, открывает соединение, отправляет все полученные сообщения, закрывает соединение и возвращает объект Transport.

Это работает, но я чувствую, что не использую все преимущества ExecutorService, имея фиксированное количество потоков, которые выполняются в течение всего срока службы приложения. Кроме того, я сам управляю рабочей очередью, а не позволяю фреймворкам параллелизма обрабатывать ее. Как другие реализовали бы эту функциональность? Лучше ли обернуть каждое входящее сообщение в Runnable, а затем выполнить логику отправки?

Спасибо, любые комментарии приветствуются.

Райан


Ответы:


1

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

Например, вы можете создать вызываемую «MailSendingTask», которая содержит MimeMessage и упаковывает отправку почты. Поставьте в очередь эти MailSendingTasks, отправив их своему исполнителю. Теперь ваш Executor решает, сколько потоков будет создано (настройте его, установив нижнюю и верхнюю границы пула потоков)

Вам нужно всего лишь создать 2 или 3 класса/интерфейса

  • один интерфейс MailService, который предоставляет простой метод отправки (MimeMessage msg)
  • один класс MailServiceImplementation, который реализует MailService и содержит ссылку на настроенный исполнитель
  • один класс MailSenderTask, реализующий вызываемый интерфейс, который содержит ссылку на объект MimeMessage и выполняет отправку почты.

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

Если вы хотите добавить «отмену», вам следует взглянуть на классы Future и FutureTask.

28.09.2009
  • Хорошо, думая об этом с точки зрения подхода, ориентированного на задачи, моя задача: взять как можно больше сообщений из очереди без блокировки и отправить с использованием одного транспортного соединения. Итак, тогда я мог бы реализовать метод run() (или call() ), как: если (по крайней мере, одно сообщение может быть принято без блокировки) продолжать принимать до тех пор, пока не заблокируется, затем отправить еще (блокировать до получения сообщения) продолжать принимать до блокировки очередной раз ? 28.09.2009
  • Хорошо, думаю, я понял. Вы можете использовать ConcurrentLinkedQueue, который можно использовать во всех потоках отправки. Просто добавьте MimeMessages в очередь и дайте вашим потокам poll(), пока она не станет пустой. Вы не должны знать о синхронизации при выборе этой реализации. 29.09.2009

  • 2

    Заключение сообщений в Runnable заставит вас либо сделать рабочую очередь неограниченной, либо иметь дело с тем, что происходит, когда очередь заполнена. ThreadPoolExecutor дает вам несколько политик для решения этой ситуации — см. ThreadPoolExecutor javadoc для получения подробной информации. - Сдавайся, запускай сам/отбрасывай что-то

    Еще одна вещь, которую вы можете сделать, это позволить пулу потоков создавать потоки, превышающие его размер ядра, то, как потоки создаются и когда они собираются, описывается первыми 4 аргументами конструктора ThreadPoolExecutor. Насколько хорошо это работает в действительности, будет зависеть от узкого места в ресурсах.

    Кроме того, в чем преимущество BlockingQueue.poll в вашей ситуации, а не BlockingQueue.take? Оба являются прерываемыми, и у вашего потока есть только одна задача, поэтому блокировка не является нежелательной.

    28.09.2009
  • Спасибо за ваш ответ! Идея использования poll() заключалась в том, чтобы взять из очереди как можно больше сообщений без блокировки, а затем отправить их все сразу. 28.09.2009
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..