这个问题不是经常出现,平均发几千封邮件会出现一次,就是在
transport.connect(server, username, password)时出现的;
后来将其dump出来,如下所示,我还是找不出具体的原因,请哪位大牛帮忙分析下,不胜感激!
名称: Thread-23279
状态: RUNNABLE
阻塞总数:0 等待总数: 0
堆栈追踪:
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:129)
com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:110)
java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
java.io.BufferedInputStream.read(BufferedInputStream.java:237)
- 已锁定 java.io.BufferedInputStream@6a48eb
com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:89)
com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2188)
com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1699)
com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1120)
- 已锁定 com.sun.mail.smtp.SMTPTransport@f849dc
com.jmail.mail.SendMail.send(SendMail.java:88)
com.jmail.SendThread.run(SendThread.java:61)
java.lang.Thread.run(Thread.java:662)
------解决方案--------------------
transport.connect(server, username, password)
这一句有反复执行吗?
如果连接上了服务器,则不需要再执行这行了,再去connect已经连接上的服务,有可能会引发问题。这一句执行一次就好。当连接继开时再去重连。
------解决方案--------------------
嗯。。。
每一次开一个线程,这样可能会有前一个线程未关闭连接,后一个线程又重连的情况吧?
另外,每发一个弄个线程,发一个万,要弄一万个线程?用线程池也好过这种方式吧,而且connect也只需要连接一次,要那么多次connect,再close干嘛。
------解决方案--------------------
个人觉得也不一定要用这么多线程去做。循环发送不行吗?比如:
MimeMessage msg = new MimeMessage(session);
Transport t = session.getTransport("smtp");
...........
t.connect();
for (int i = 0; .....) {
t.sendMessage(msg, new Address[] { recipients[i] });
Thread.sleep(100);//防止发的太多,sleep一小会。
}
t.close();
------解决方案--------------------
根本原因是什么,我也只是猜测。
有只能是楼主采用多线程的方式,connect造成的问题,javamail api, connect方法有这么一句:
It is an error to connect to an already connected service.
另外网络、邮件服务器也都可能出现问题,就是我们用IE打开自己的邮箱,去发一封邮件,也可能出现发送失败的情况,更何况楼主一直不停的发。所以一次很顺的发送大批量邮件,中间出现问题也应该是正常情况(具体我也没测试过)。
不过刚才有一个帖子让我想起,发送的时候,可以一次发送多个人,就好像用邮箱发邮件时,也可以抄送一样。
- Java code
Message msg = new MimeMessage(session);msg.setFrom(new InternetAddress("from@163.com"));msg.setSubject("test javamail");msg.setRecipients(RecipientType.TO, InternetAddress.parse("user1@163.com,user2@163.com,user3@163.com"));//可添加多个接收地址Transport.send(msg);