多執行緒 同時處理多請求 帶超時時間

2022-05-09 07:30:10 字數 3726 閱讀 1477

在研究執行緒相關的api時,發現了future.get(timeout, unit)方法,意思是在指定的時間內會等待任務執行,超時則拋異常。激動之餘趕緊試了下:

修改下parallelservice中的介面(三個請求的用時分別是1s、2s、10s):

@slf4j

@service

public

class

parallelservice

catch

(interruptedexception e)

return"a";}

public

string requestb()

catch

(interruptedexception e)

return"b";}

public

string requestc()

catch

(interruptedexception e)

return"c";}

}

增加測試方法(超時時間是3s,也就是說超過3s的任務會被扔掉):

/*

* * 多執行緒請求(帶超時時間)

*/"/test4")

public

void

test4() );

for (int i = 0; i < futurelist.size(); i++)

", result);

list.add(result);

} catch

(timeoutexception e) ,超時

", i);

//強制取消該任務

future.cancel(true

); }

catch

(exception e)

}//停止接收新任務,原來的任務繼續執行

executor.shutdown();

log.info(

"多執行緒,響應結果:{},響應時長:{}

", arrays.tostring(list.toarray()), system.currenttimemillis() -start);

}

傳送請求,結果:

表面上看感覺效果達到了,時長超過3s的請求被扔掉了。但仔細看發現了個問題:響應時長為啥是5s左右,不應該是3s嗎?

在future.get方法前後加上日誌:

long start1 =system.currenttimemillis();

unit):在指定的時間內會等待任務執行,超時則拋異常。

string result = future.get(3

, timeunit.seconds);

log.info(

"結果:{},用時:{}

", result, system.currenttimemillis() -start1);

list.add(result);

重新請求一次,結果:

好奇怪,為啥requestb的用時是1s呢?通過多次試驗終於發現了真相:

future.get(timeout, unit):在指定的時間內會等待任務執行,超時則拋異常。

任務執行的時間是獲取到結果的時長。由於每個任務是同時執行的, 但是獲取結果時,是阻塞的,也就是序列獲取的,所以每個任務獲取結果的時長 = 當前任務請求時長 - 上乙個任務請求時長。

由此可以計算出任務a時長是1s,任務b是2-1=1s,任務c是10-2=8s。

至於總時長5s = 任務b獲取結果用時2s + 超時時間3s

結論:當只有乙個任務時,超時時間有效,當多個任務執行時,超時時間無效

那如果將future.get(timeout, unit) 方法放在乙個子執行緒中,非同步去獲取結果,能達到效果嗎?拭目以待:

/*

* * 多執行緒請求(帶超時時間)

*/"/test5")

public

void

test5() );

for (int i = 0; i < futurelist.size(); i++) ,用時:{}

", result, system.currenttimemillis() -start1);

list.add(result);

} catch

(timeoutexception e) ,超時

", j);

future.cancel(

true

); }

catch

(exception e)

});}

//停止接收新任務,原來的任務繼續執行

executor.shutdown();

while (true

) ,響應時長:{}

", arrays.tostring(list.toarray()), system.currenttimemillis() -start);

break

; }}}

請求一次,結果:

完美達到我們的效果!再來壓測一下:

從jmeter結果可以看到:平均響應時長:3438ms,最小響應時長:2415ms,最大響應時長:4707ms,tps:8.1/sec

結論:雖然**複雜一點,但是效果基本達到了,不過有一點,開啟的執行緒的翻了一倍,對記憶體消耗比較大

再次研究api,找到了最終的大招,使用invokeall(tasks, timeout, unit)方法:

/*

* * 多執行緒請求(帶超時時間)

*/"/test6")

public

void

test6() );

try", system.currenttimemillis() -start1);

for (int i = 0; i < futurelist.size(); i++)

catch

(cancellationexception e)

", i);

} catch

(exception e) }}

catch

(interruptedexception e1)

//停止接收新任務,原來的任務繼續執行

executor.shutdown();

log.info(

"多執行緒,響應結果:{},響應時長:{}

", arrays.tostring(list.toarray()), system.currenttimemillis() -start);

}

請求一次,結果:

完美,太完美了,再來壓測一下:

從jmeter結果可以看到:平均響應時長:2114ms,最小響應時長:2007ms,最大響應時長:2485ms,tps:13.3/sec

結論:**很簡潔,效率也很好

Ajax多請求處理

ajaxsingle function settings a jaxs etti ngs,sett ings if jqx hr o ptio ns.c lass name jq xhr opti ons.clas snam e a bort j qxhr opt ions cla ssna me ...

多執行緒請求網頁

這裡主要的還是開啟多執行緒 多執行緒會對num這個全域性變數進行修改,主要是用來計算訪問的次數,所以的要加乙個執行緒鎖。最後別看我執行緒開的多,但是只刷了十幾秒,不過十幾秒的訪問了就已經破百了 附上 import requests import csv import random import ti...

curl多執行緒批量請求

測試經常遇到檢視大資料量url請求是否正常。單執行緒跑的太慢 可以自定義執行緒數進行跑,細節不多說,其實我也是上網上湊的,拿下來修修改改能用即可。bin bash ttime date y m d h m s 允許的執行緒數 thread num 5 定義描述符為9的管道 mkfifo tmp ex...