Apache Email 遇到的线程释放慢问题

Java-Email 专栏收录该内容
1 篇文章 0 订阅

在实习中,需要做一个系统的发送邮件功能,因为是群发,需要发送给公司1500多人,因为是建立公告后,判断公告的重要性,重要则发送群邮,因此不能通过同步来实现,只能通过异步发送,一封邮件同时发给1500个人是不太现实的,所以开始的时候,将每封邮件发送给200个人,通过多线程并发,启动8个线程发送这8封邮件。如下代码:

 private static ExecutorService executorService = Executors.newFixedThreadPool(3);

    //发6封邮件,一封200个人
    @org.junit.Test
    public void test01() throws Exception {
        //获取数据库内容
        final HtmlEmail email = new HtmlEmail();
        email.setSocketTimeout(30000);
        email.setSocketConnectionTimeout(30000);
        email.setCharset("UTF-8");
        email.setHostName("smtp.xxxx.com");
        email.setSmtpPort(25);
        //设置发送人
        email.setFrom("111@qq.com", "111");
        email.setAuthentication("111@qq.com", "xxx");
        email.setSubject("主题");
        email.setMsg("内容");

        //循环6次、发送6封邮件,每封邮件发200人
        for (int k = 0; k < 6; k++) {
            for (int i = 0; i < 200; i++) {
                email.addTo("222@qq.com", "222");
            }
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        email.send();
                    } catch (EmailException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        //将邮件信息插入数据库
    }

    查看线程栈可以发现,线程一直是Runnable状态,如下代码:

"pool-2-thread-2@20561" prio=5 tid=0x86f nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at java.net.SocketInputStream.socketRead0(SocketInputStream.java:-1)
      at java.net.SocketInputStream.read(SocketInputStream.java:129)
      at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:79)
      at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
      at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
      - locked <0x52e4> (a java.io.BufferedInputStream)
      at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:57)
      at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:1070)
      at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:986)
      at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:197)
      at javax.mail.Service.connect(Service.java:274)
      at javax.mail.Service.connect(Service.java:91)
      at javax.mail.Service.connect(Service.java:76)
      at com.sun.mail.smtp.SMTPTransport.connect(SMTPTransport.java:104)
      - locked <0x52e5> (a com.sun.mail.smtp.SMTPTransport)
      at javax.mail.Transport.send(Transport.java:94)
      at javax.mail.Transport.send(Transport.java:48)
      at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1411)
      at org.apache.commons.mail.Email.send(Email.java:1448)
      ......
      ......
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
      at java.lang.Thread.run(Thread.java:662)

    线程一直是Runnable状态持续10几分钟,折腾了很长时间没有发现出问题,期间有怀疑过是否是Hibernate的缓存导致邮件发送的时间延迟, 后来无意中测试了,发送6封邮件,每封发一个人,如下代码:

//发6封邮件,每封发1个人
    @org.junit.Test
    public void test02() throws Exception {
        final HtmlEmail email = new HtmlEmail();
        email.setSocketTimeout(30000);
        email.setSocketConnectionTimeout(30000);
        email.setCharset("UTF-8");
        email.setHostName("smtp.xxxx.com");
        email.setSmtpPort(25);
        //设置发送人
        email.setFrom("111@qq.com", "111");
        email.setAuthentication("111@qq.com", "xxx");
        email.setSubject("主题");
        email.setMsg("内容");

        //循环6次、发送6封邮件,每封邮件发200人
        for (int k = 0; k < 6; k++) {
            email.addTo("222@qq.com", "222");
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        email.send();
                    } catch (EmailException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        //将邮件信息插入数据库
    }

    这时,邮件发送很快,等待时间基本看不到,才发觉,猫腻藏在邮件发送的人数上。
    猜测:一封邮件发送200个人的时候,线程启动后,一直在Runnable,可能是一封邮件发送给200个人,邮件服务器应付不回来,只能慢慢运行、发送邮件,直到200封邮件发送出去后,线程才释放资源。
    后来才将代码改为一封一封的发送,一次群发的速度,很大一部分取决于邮件服务器。在线程池限制在20个前提下,发了1500封邮件差不多要1个小时。。。。



展开阅读全文
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值