需求:
/**
* 注册登录发送邮件案例
* 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可以用来判断其他线程是否被中断。