版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_23888451/article/details/80535149
线程基础知识复习
通过Callable和FutureTask创建线程,步骤如下:
- 创建Callable接口的实现类,并实现Call方法;
- 创建Callable实现类的实现,使用FutureTask类包装Callable对象,该FutureTask对象封装了Callable对象的Call方法的返回值;
- 使用FutureTask对象作为Thread对象的target创建并启动线程;
- 调用FutureTask对象的get()方法来回去子线程执行结束的返回值。
public class Demo{
public static void main(String[] args){
Callable call = new MyCallable();
FutureTask<Object> task = new FutureTask<Object>(call);
Thread t = new Thread(task);
t.start();
try {
System.out.println(task.get());//可以作为Future类型对象得到线程运算返回值
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyCallable implements Callable<Object>{
@Override
public Object call() throws Exception{
System.out.println(Thread.currentThread().getName());
return null;
}
}
通过线程池创建线程,如下:
public class ThreadDemo{
public static void main(String[] args){
FutureTask<Integer> futureTask = new FutureTask<Integer>(new CallbleThread());
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(futureTask);//也可以使用execute,证明其是一个Runnable类型对象
executor.shutdown();
while(!futureTask.isDone()){
System.out.println("子线程还没做完,我再睡会");
TimeUnit.SECONDS.sleep(1);
}
try {
System.out.println("子线程运行的结果:"+futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class CallbleThread implements Callable<Integer>{
@Override
public Integer call() throws Exception{
System.out.println("线程池创建的线程:"+Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(2);
return 2;
}
}
发送邮件
在独立线程中发送邮件:
public class SendMailUtil{
private final Logger logger = Logger.getLogger(this.class);
public Boolean sendMailWithTask(Mailbox mailbox){
ExecutorService exec = executors.newCachedThreadPool();
MailTask task = new MailTask();
task.mailbox = mailbox;
String failReason = null;
Future<Boolean> future = exec.submit(task);
Boolean taskResult = false;
try{
taskResult = future.get(120,TimeUnit.SECONDS);//等待计算结果,最长等待120s,120s后终止任务
taskResult = true;
}catch(InterruptedException e){
failReason = "主线程在等待计算结果时被中断!" + e.getMessage();
}catch(ExecutionException e){
failReason = "主线程等待计算结果,但计算抛出异常!" + e.getMessage();
}catch(TimeoutException e){
failReason = "主线程等待计算结果超时,因此中断任务线程!" + e.getMessage();
}finally{
if(failReason!=null){
logger.info(failReason);
}
}
return taskResult ;
}
class MailTask implements Callable<Boolean>{
public Mailbox mailbox = null;
public Boolean call() throws Exception{
result = MailSender.send(mailbox);
return result;
}
}
}
MailSender类
public class MailSender{
public static boolean send(Mailbox mailbox) throws Exception {
// 判断是否需要身份认证
MyAuthenticator authenticator = null;
Properties pro = mailbox.getProperties();
// 如果需要身份认证,则创建一个密码验证器
if (mailbox.getValidate()) {
String password = mailbox.getPassword();
authenticator = new MyAuthenticator(mailbox.getEmail(),password );
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session sendMailSession = Session.getInstance(pro, authenticator);
// 根据session创建一个邮件消息
Message mailMessage = new MimeMessage(sendMailSession);
// 创建邮件发送者地址
Address from = new InternetAddress(mailbox.getEmail());
// 设置邮件消息的发送者
mailMessage.setFrom(from);
// 创建邮件的接收者地址,并设置到邮件消息中
Address to = new InternetAddress(mailbox.getToAddress());
// Message.RecipientType.TO属性表示接收者的类型为TO
mailMessage.setRecipient(Message.RecipientType.TO, to);
//抄送
//mailMessage.setRecipient(Message.RecipientType.CC, new InternetAddress(mailbox.getEmail()));
// 设置邮件消息的主题
mailMessage.setSubject(mailbox.getSubject());
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
//MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象
Multipart mainPart1 = new MimeMultipart();
BodyPart html = new MimeBodyPart();//创建一个包含HTML内容的MimeBodyPart
html.setContent("hehehe","text/html; charset=utf-8");//设置HTML内容
mainPart1.addBodyPart(html);
//将MiniMultipart对象设置为邮件内容
mailMessage.setContent(mainPart1);
// 发送邮件
Transport.send(mailMessage);
return true;
}
}
MailBox类:
public class Mailbox {
private Integer mailboxId;
private String email;
private String password;
private String protocol;//imap/imaps/pop3/pop3s 邮箱协议 --SMTP管‘发’,POP3/IMAP管‘收’
private String mailServerHost;// 箱服务器的IP(或主机地址)
private String mailServerPort;// 服务器的端口
private String passwordEncrypt;// 登陆邮件服务器的密码
private Boolean validate;// 是否需要身份验证
private String toAddress;
private String subject;
private String connectType;//针对邮箱协议连接类型
@JsonIgnore
public Properties getProperties() {
Properties p = new Properties();
p.put("mail."+this.protocol+".host", this.mailServerHost);
p.put("mail."+this.protocol+".port", this.mailServerPort);
p.put("mail."+this.protocol+".auth", validate);
if("TLS".equals(this.connectType)){
p.put("mail."+this.protocol+".starttls.enable", true);
}else if("SSL".equals(this.connectType)){
p.put("mail."+this.protocol+".ssl.enable", true);
}
return p;
}
//属性的getter和setter方法略
}