需求:
/**
* 注冊登錄發送郵件案例
* 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可以用來判斷其他線程是否被中斷。
