日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring多线程批量发送邮件(ThreadPoolTaskExecutor)

發布時間:2024/9/30 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring多线程批量发送邮件(ThreadPoolTaskExecutor) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1,需求:使用多線程批量發送郵件

需要批量發送郵件大概400封左右,但是因為發送郵件受網絡限制,所以經常導致等待超時。所以就想到了使用多線程來發郵件,因為是異步的所以返回結果不受發郵件影響。

2,思路:使用spring的ThreadPoolTaskExecutor,用10個線程循環400個任務,完成任務后關閉

首先創建一個發郵件的Task(任務),只是負責發郵件。

然后創建一個執行任務的類,讓ThreadPoolTaskExecutor循環執行

創建一個ThreadPoolTaskExecutor的bean配置交給spring管理

3,代碼:SendEmailTask.java(任務類)?SendEmailThread.java(執行任務類)?email.xml(ThreadPoolTaskExecutor的配置)

SendEmailTask.java:

package com.XXX.core.base.utils.task;import com.XXX.core.base.utils.EmailUtil;/** * 發送郵件任務類 * @author chenminchang * @date 2017年3月20日 下午4:40:42 */ public class SendEmailTask implements Runnable {private String toemail;private String title;private String content;public SendEmailTask(String toemail, String title, String content){this.toemail = toemail;this.title = title;this.content = content;}@Overridepublic void run() {EmailUtil.send(toemail, title, content);//send是自行封裝的發郵件的方法}} SendEmailThread.java:

package com.XXX.core.base.utils.task;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;/** * 多線程批量發送郵件 * @author chenminchang * @date 2017年3月20日 下午4:54:35 */ public class SendEmailThread {private static Logger log = LoggerFactory.getLogger(SendEmailThread.class);private String[] toEmails;//需要發送的郵箱private String title;//需要發送的標題private String content;//需要發送的內容private ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:**/applicationContext**.xml");private ThreadPoolTaskExecutor poolTaskExecutor = (ThreadPoolTaskExecutor)ctx.getBean("threadPool");public SendEmailThread(String title, String content, String... toEmails) {this.toEmails = toEmails;this.title = title;this.content = content;}/*** 使用多線程執行任務* * @author chenminchang* @create 2017年3月22日上午10:50:31*/public void runTask() {if (poolTaskExecutor == null) {log.debug("the poolTaskExecutor is null");} else {if (toEmails != null && toEmails.length > 0) {if (toEmails.length < poolTaskExecutor.getCorePoolSize())//當任務數小于創建的線程poolTaskExecutor.setCorePoolSize(toEmails.length);for (String email : toEmails) {try {poolTaskExecutor.execute(getNextTask(email, this.title , this.content));} catch (Exception ex) {ex.printStackTrace(); }}}}}/*** 獲取新任務* @param toemail* @param title* @param content* @return* @author chenminchang* @create 2017年3月20日下午5:15:07*/private Runnable getNextTask(String toemail, String title, String content) {return new SendEmailTask(toemail, title, content);}} ?threadPool.xml: 將此文件添加到applicationContent.xml相同的文件夾下

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="threadPool"class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><!-- 核心線程數,默認為1 --><property name="corePoolSize" value="10" /><!-- 最大線程數,默認為Integer.MAX_VALUE --><property name="maxPoolSize" value="100" /><!-- 隊列最大長度,一般需要設置值>=notifyScheduledMainExecutor.maxNum;默認為Integer.MAX_VALUE --><property name="queueCapacity" value="500" /><!-- 線程池維護線程所允許的空閑時間,默認為60s --><property name="keepAliveSeconds" value="60" /><!-- 完成任務自動關閉 , 默認為false--><property name="waitForTasksToCompleteOnShutdown" value="true" /><!-- 核心線程超時退出,默認為false --><property name="allowCoreThreadTimeOut" value="true" /><!-- 線程池對拒絕任務(無線程可用)的處理策略,目前只支持AbortPolicy、CallerRunsPolicy;默認為后者 --><property name="rejectedExecutionHandler"><!-- AbortPolicy:直接拋出java.util.concurrent.RejectedExecutionException異常 --><!-- CallerRunsPolicy:主線程直接執行該任務,執行完之后嘗試添加下一個任務到線程池中,可以有效降低向線程池內添加任務的速度 --><!-- DiscardOldestPolicy:拋棄舊的任務、暫不支持;會導致被丟棄的任務無法再次被執行 --><!-- DiscardPolicy:拋棄當前任務、暫不支持;會導致被丟棄的任務無法再次被執行 --><bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /></property></bean> </beans>

這里需要注意的是如果沒有allowCoreThreadTimeOut這項配置,即使waitForTasksToCompleteOnShutdown設為true,線程完畢是不會關閉的,只是會轉為駐留狀態,還有一點是 每次創建的線程都會產生新的線程,老線程不關閉,新線程重新生成,這樣導致線程越來越多。大家可以根據Java VisualVM去測試,所以必須加上allowCoreThreadTimeOut屬性
然后需要注意的是在 applicationContent.xml中引入threadPool.xml,在applicationContext.xml中加入?<import resource="threadPool.xml" />

4,測試SendEmailThreadTest.java

package com.XXX.core.base.utils.task;import java.util.ArrayList; import java.util.List;import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.XXX.core.base.utils.EmailUtil;/** * * @author chenminchang * @date 2017年3月20日 下午6:39:42 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath*:**/applicationContext**.xml" }) public class SendEmailThreadTest {/*** 測試線程批量發送郵件* * @author chenminchang* @create 2017年3月22日上午11:59:48*/@Testpublic void testSendEmailThread() {List<String> toEmailList = new ArrayList<>();for (int i = 0; i < 50; i++) {toEmailList.add("你的@郵箱");}EmailUtil.sendBatchUseThread("注冊用戶", "您已成為注冊用戶", toEmailList.toArray(new String[toEmailList.size()]));} } 5,結果

6,推薦

這里給大家推薦一篇寫的不錯的關于線程池配置的文章:線程池ThreadPoolExecutor參數設置

總結

以上是生活随笔為你收集整理的Spring多线程批量发送邮件(ThreadPoolTaskExecutor)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。