在研究執行緒相關的api時,發現了future.get(timeout, unit)方法,意思是在指定的時間內會等待任務執行,超時則拋異常。激動之餘趕緊試了下:
修改下parallelservice中的介面(三個請求的用時分別是1s、2s、10s):
@slf4j增加測試方法(超時時間是3s,也就是說超過3s的任務會被扔掉):@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";}
}
/*傳送請求,結果:* * 多執行緒請求(帶超時時間)
*/"/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...