文章目錄
- 前言
- 思路
- 總結
前言
這是蘑菇街一面面試官問我的一個問題,他說:如果有這么一個場景,我執行業務的時候,不想讓業務執行時間超過一定時間,如果超出就停止執行,你怎么來設計!
思路
我們在學習Java并發編程的時候,那些常見的方法大多都有設定超時時間的引數,我們可以根據這一思路來設計超時結束任務的方案,我這里用到的是Thread.join()方法,先來解釋下join方法吧,
join()方法:如果一個執行緒A執行了thread.join()陳述句,其含義是:當前執行緒A等待thread執行緒終止之后才從thread.join()回傳,執行緒Thread除了提供join()方法之外,還提供了join(long millis)和join(long millis,int nanos)兩個具備超時特性的方法,這兩個超時方法表示,如果執行緒thread在給定的超時時間里沒有終止,那么將會從該超時方法中回傳,摘自《Java并發編程的藝術》
我們來看下join的原始碼:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
//正常來說,我們會進入到這里,進入到回圈里,直到呼叫join方法的執行緒執行完畢之后或者超出時間限制了,才退出,
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
其實我感覺書中對join的解釋還是有那么一點欠缺的,我認為是:當在主執行緒A中呼叫另一個執行緒B的join方法意味著,從一開始的A、B兩個執行緒并發執行變為串行執行的了,也就是將B執行緒插入到A執行緒中,然后等待B執行緒執行完成以后,再執行剩下的A執行緒的任務了,如果這個join方法帶有超時引數的話,可以理解為,在這段時間內,A等待B執行緒執行(串行),一旦超出這個時間,兩個執行緒又會回到并發執行的狀態了,
回到我們之前的問題 ,我們想設計一個超時退出的介面,就可以利用這個帶有超時引數的join來實作,來看看我的代碼,注意看注釋,
package com.markus.basic.Java多執行緒.方法超時問題;
/**
* Author:markusZhang
* Date:Create in 2020/10/8 12:57
* todo:
*/
public class JoinDemo {
public static void main(String[] args){
Thread method = new Thread(new ThreadMethod());
//呼叫方法
method.start();
try {
method.join(2000);//規定業務介面執行不能超過的時長
} catch (InterruptedException e) {
e.printStackTrace();
}
method.interrupt();//呼叫中斷很重要,如果不呼叫的話,就會回到上面說的,兩個執行緒并發執行,就起不到效果了,
}
}
class ThreadMethod implements Runnable{
@Override
public void run() {
try {
Thread.sleep(3000);//執行業務
System.out.println("方法呼叫完成");
} catch (InterruptedException e) {
//e.printStackTrace();
System.out.println("方法呼叫超時");
}
}
}
總結
當然了,設計任務執行超時退出有很多種方案,這個只是其中一種,在開發中,我們需要多注意下那些帶有超時引數的方法,說不定也是可以設計的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/167041.html
標籤:AI
上一篇:第六章 訪問權限控制
