下面的这个方法是发邮件的抽象出来的一个公用方法:
String[] to 表示收件人列表;
subject 邮件主题;
templateName 邮件末班,用velocity写的,
Map params 参数,用来填充velocity中的某些字段取值的
public void sendHtmlWithTemplate(String[] to, String subject, String templateName, Map<String, Object> params) {
final MimeMessage mimeMessage = mailSender.createMimeMessage();
try {
final MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setFrom(simpleMailMessage.getFrom());
if (ENV_ONLINE.equals(environment)) {
messageHelper.setTo(to);
messageHelper.setSubject(subject);
} else {
messageHelper.setTo(adminEmail);
messageHelper.setSubject(subject + Arrays.asList(to));
}
messageHelper.setSentDate(new Date());
final String content = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, templateName, "UTF-8",
params);
final String[] logTo = to;
messageHelper.setText(content, true);
new Thread() {
@Override
public void run() {
mailSender.send(mimeMessage);
logger.error("Mailsentto: " + Arrays.asList(logTo) + "\nContent: " + content);
}
}.start();
} catch (Exception e) {
logger.error("emailServiceError error:" + e.getMessage(), e);
}
}
在上面的发邮件的代码中,使用了内部类如下:
new Thread() {
@Override
public void run() {
mailSender.send(mimeMessage);
logger.error("Mailsentto: " + Arrays.asList(logTo) + "\nContent: " + content);
}
}.start();
我觉得在这个地方做这个控制是很恰当的吧,为什么team leader让我删掉这个new Thread()的部分。
原话:“把new Thread全部删掉,这些邮件发送不了的bug都没有暴露出来; 邮件发送模块的代码采用异步发送方式,失去异常事务回滚的能力,new Thread要全部删除;” 不懂是什么意思啊?
问题:
1.为什么要去掉new Thread()?
2.在什么样的并发业务场景下,需要使用new Thread()这样的方式?有没有更好的解决方法?
3.在并发场景下,使用new Thread().start()的方式有什么弊端?每次new Thread新建对象性能会很差么?邮件服务也是当触发某个业务规则的时候,可能需要大量发送一下邮件,用线程池好不好呢?
@Youming telah pun menyebut aspek menyusahkan kelas dalaman tanpa nama. Biar saya terangkan berdasarkan perniagaan anda:
Mengikut logik kod sedia ada, kaedah
yang kami dedahkan kepada dunia luar Mulakan urutan untuk menghantar e-mel secara tidak segerak, kerana bagi pemanggil, anda sebenarnya perlu memberitahu sama ada menghantar e-mel itu berjaya kali ini, dan jika ia gagal/pengecualian berlaku, apakah adalah punca kegagalan itu. Jika anda mengikuti rancangan anda yang sedia ada, dunia luar mungkin merasakan bahawa tidak kira sama ada e-mel dihantar berjaya atau gagal, dunia luar tidak akan melihatnya, yang bermaksud bahawa e-mel itu tidak dapat diteruskan dan akan dicuba semula selepas beberapa ketika . Jadi menghantar e-mel secara tidak segerak harus diserahkan kepada pemanggil anda, bukan dalam kaedah andasendHtmlWithTemplate
yang perkhidmatan e-mel kami harus dedahkan kepada dunia luar haruslah kaedahmailSender.send
, bukansendHtmlWithTemplate
, jadi tidak perlu mendedahkan semula kaedahObjek tanpa nama sangat mudah, tetapi objek tanpa nama juga syaitan Jika ia tidak digunakan dengan betul, aplikasi anda akan runtuh. Ambil contoh anda sebagai contoh Jika anda tidak mengawal parameter menghantar e-mel, contohnya, jika anda terus menunggu selepas tamat masa berlaku semasa penghantaran, maka urutan ini akan menjadi hantu yang sunyi. Lepaskan, adakah ini yang harus dilakukan oleh pengaturcara?
Jika anda bertanya mengapa kepala anda meminta anda mengalih keluar tempat ini, saya hanya boleh mengatakan bahawa dia tidak cukup mempercayai keupayaan anda, jadi dia tidak berani untuk membiarkan anda mengawal syaitan ini.
Awak tanya senario apa yang sesuai, saya cuma boleh katakan tiada senario yang sesuai, hanya orang yang berkebolehan.
Jika anda ingin menghantar sejumlah besar e-mel, anda boleh membuat baris gilir Jika terdapat terlalu banyak utas, ia mungkin tidak bagus.
Maaf, saya baru nampak masalahnya sekarang.
Untuk butiran, sila rujuk kepada jawapan @iMouseWu dan @有明.
Jika anda pernah menulis js, anda boleh memahami bahawa
new Thread()
di sini adalah bersamaan dengan permintaanajax
, yang merupakan tingkah laku tak segerak Sebelum tugasan urutan selesai, kaedah itu telah kembali kepada pemanggil (dan tiada Pengecualian yang disebabkan oleh menghantar e-mel akan dibuang), itulah yang dikatakan oleh ketua anda "Pepijat yang tidak boleh menghantar e-mel ini belum didedahkan" .Jika anda menganggap jumlah konkurensi adalah besar, anda boleh menggunakan
redis
+kafka
(atau komponen mesej lain) untuk memberitahu perkhidmatan e-mel untuk menghantar e-mel dalam bentuk mesej.