2009-09-28 64 views
3

我正在編寫一個消息處理應用程序(電子郵件),我想要一個傳出隊列。我設計的方式是使用一個單例隊列類ThreadedQueueSender,它由Executor Service和BlockingQueue支持。此外,javax.mail.Transport對象的線程池用於獲取和釋放與傳出SMTP服務器的連接。Java電子郵件發送隊列 - 發送儘可能多的消息的固定線程數

該類公開了一種方法add(MimeMessage),它將消息添加到工作隊列(BlockingQueue)。

在類的實例中,ExecutorService初始化爲ThreadPoolExecutor具有固定數量的線程,可以說5.每個線程的run()方法是無限循環,只有當它檢測到中斷時(ExecutorService.shutdownNow()被調用)退出。

此運行方法使用BlockingQueue.poll()採取形式交往從工作隊列中,直到沒有更多的可用而不阻斷,然後請求從連接池中一個Transport對象,打開連接,發送所有其檢索的郵件,然後關閉連接並返回Transport對象。

這可行,但我覺得我沒有充分利用ExecutorService,因爲它擁有爲應用程序的生命週期運行的固定數量的線程。另外,我自己管理工作隊列,而不是讓併發框架處理它。其他人將如何實現此功能?將每個傳入消息包裝在Runnable中,然後執行發送邏輯是否更好?

謝謝你,任何意見表示讚賞。

瑞安

回答

1

您應該爲執行者服務應完成的每項工作創建任務。

例如,您可以創建一個可調用的「MailSendingTask」來保存MimeMessage並封裝郵件發送。通過將這些MailSendingTasks提交給您的執行程序來排隊。現在,您的執行人決定多少線程將被創建

你只需要創建2個或3個班(通過設置上限和線程池範圍的配置它)/接口

  • 一個MailService的接口,提供了一個簡單的發送(的MimeMessage MSG)方法實現MailService的並保持到已配置的執行
  • 一個類MailSenderTask參考實施保存到的MimeMessage對象的引用和它執行郵件發送可調用接口
  • 一個MailServiceImplementation類。

你甚至可以創建一個額外的服務來管理MailSenderTask可以使用的郵件套接字連接。

如果你想添加「取消」你應該看看類Future和FutureTask

+0

好的,從一個以任務爲中心的方法來考慮它,我的任務是:「儘可能多地從隊列中取消消息而不會阻塞,並使用單個傳輸連接發送」。因此,我可以執行run()(或call())方法,如下所示: if(至少一個消息可以不阻塞地進行) 繼續執行直到塊,然後發送 else(阻塞直到消息到達) 繼續服用,直到再次阻塞 ? – purecharger 2009-09-28 19:46:00

+0

好吧,我想我明白了。您可以使用可在整個發送線程中共享的ConcurrentLinkedQueue。只需將MimeMessages添加到隊列中並讓線程poll()直到它爲空。 選擇此實現時,您不必知道同步。 – MrWhite 2009-09-28 21:47:34

0

結束語在Runnable消息會迫使你要麼使工作隊列無界或處理時,隊列已滿時會發生什麼。 ThreadPoolExecutor爲您提供了一些處理這種情況的政策 - 有關詳細信息,請參閱ThreadPoolExecutor javadoc。 - 放棄,自己運行/丟棄東西

你可以做的另一件事是允許線程池創建超出其核心大小的線程,線程是如何產生的以及何時收到的是由前4個參數ThreadPoolExecutor構造函數。這在現實中的運作情況取決於資源瓶頸。

另外,BlockingQueue.poll在您的情況中有什麼優勢,而不是BlockingQueue.take?兩者都是可以中斷的,而且你的線程只有一個任務,所以阻塞並不是不可取的。

+0

感謝您的回覆!使用poll()後面的想法是儘可能多地從隊列中取消消息而不會阻塞,然後立即發送這些消息。 – purecharger 2009-09-28 19:25:37

相關問題