需求:
/**
* 注册登录发送邮件案例
* 1 存用户信息到"用户"表 假如需要3秒
* 2 存用户上传附件到"附件"表假如需要5秒
* 3 发送邮件通知用户激活假如需要10秒
* 4 注册成功提示假如需要1秒
*
* 如果用户填写完信息点击"注册"后总共需要19秒才可以看见成功信息, 期间用户很可能会认为没有注册成功而重复点击注册按钮
* 如何缩短注册到看到成功回调信息的时间? 答案: 多线程, 由于使用sleep模拟真实情景, 但是sleep会阻塞线程所以还是要配上interrupt方法使用真实情景不需要的
* 每次创建都需要不断的创建新的线程, 浪费内存开销, 怎么解决? 答案: 使用线程池(类似于数据库连接池的原理)
*/
正常处理流程从上到下一次执行
public static void main(String[] args) throws InterruptedException {
//PS: 使用 Thread.sleep(long millis);演示等待时间效果
Thread.sleep(1000 * 3);
System.out.println("1 存用户信息到\"用户\"表 成功");
Thread.sleep(1000 * 5);
System.out.println("2 存用户上传附件到\"附件\"表 成功");
Thread.sleep(1000 * 10);
System.out.println("3 发送邮件通知用户激活 成功");
Thread.sleep(1000);
System.out.println("4 注册成功提示");
System.out.println("用户已经等的不耐烦了......");
}
输出如下(自己运行看效果): 基本上是一个一个往控制台上蹦
1 存用户信息到"用户"表 成功
2 存用户上传附件到"附件"表 成功
3 发送邮件通知用户激活 成功
4 注册成功提示
用户已经等的不耐烦了......
使用多线程解使用sleep方法模拟时长由于调用sleep函数后会阻塞当前线程, 可以使用interrupt(); 方法使当前执行的线程退出阻塞状态
public static void main(String[] args) {
// 1
Thread userInfoThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("保存用户信息到用户表开始...");
try {
Thread.sleep(1000 * 3);
System.out.println("1 存用户信息到\"用户\"表 成功");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("保存用户信息到用户表结束...");
}
});
userInfoThread.start();
System.out.println(userInfoThread.getName());
System.out.println("用户基本信息线程关闭");
Thread.interrupted();
// 2
Thread attachmentThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("保存附件信息到附件表开始...");
try {
Thread.sleep(1000 * 5);
System.out.println("2 存用户上传附件到\"附件\"表 成功");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("保存附件信息到附件表结束...");
}
});
attachmentThread.start();
System.out.println(attachmentThread.getName());
System.out.println("附件信息线程关闭");
Thread.interrupted();
Thread mailThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("处理发送邮件开始...");
try {
Thread.sleep(1000*10);
System.out.println("3 发送邮件通知用户激活 成功");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("处理发送邮件结束...");
}
});
mailThread.start();
System.out.println(mailThread.getName());
System.out.println("邮件线程关闭");
Thread.interrupted();
Thread callBackThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("4 注册成功提示");
}
});
callBackThread.start();
System.out.println(callBackThread.getName());
System.out.println("注册回调信息线程关闭");
Thread.currentThread().interrupt();
}
输出如下:
Thread-0
保存用户信息到用户表开始...
用户基本信息线程关闭
Thread-1
附件信息线程关闭
保存附件信息到附件表开始...
Thread-2
邮件线程关闭
处理发送邮件开始...
Thread-3
注册回调信息线程关闭
4 注册成功提示
1 存用户信息到"用户"表 成功
保存用户信息到用户表结束...
2 存用户上传附件到"附件"表 成功
保存附件信息到附件表结束...
3 发送邮件通知用户激活 成功
处理发送邮件结束...
注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。