[英]How to call a function in java if the program doesn't return anything after n seconds
我有一個這樣的功能:
public boolean doLogin() {
try {
somemethodForLogin();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
在這種情況下,如果somemethodForLogin()
花費的時間比預期的長,例如8秒,我想返回false
或引發異常。 我怎樣才能做到這一點?
我在somemethodForLogin()
之前添加了類似的內容:
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
System.out.println("Returning after 8 seconds wait");
}
}, 8000);
但是,即使調用成功,也總是會涉及到這一點。
您可以使用compleable future來調用登錄名,然后使用超時來檢索結果:
try {
CompletableFuture.runAsync(() -> somemethodForLogin())
.get(8, TimeUnit.SECONDS);
return true;
}catch(TimeoutException timeoutException) {
//Timeout handline here
return false; //or call other function
}
上面的lambda是Supplier
而不是Runnable
。
CompletableFuture的get
方法記錄如下:
如有必要,最多等待給定時間以完成此將來,然后返回其結果(如果有)。
TimeoutException-如果等待超時
編輯:
上面使用CompletableFuture<Void>
因為調用采用了Runnable
。 如果somemethodForLogin()
返回一個值,則可以使用相同的API,但是要調用supplyAsync
:
Object loginResult = CompletableFuture.supplyAsync(() -> somemethodForLogin())
.get(8, TimeUnit.SECONDS);
//Just change the return types accordingly.
因此,我剛剛創建了一個示例程序來解決您的問題。我認為它可以按預期工作,但是您也可以在您身邊嘗試它。
我已經在代碼注釋中解釋了代碼,因此它不是代碼轉儲。
class Test
{
// your do logic method
public boolean doLogic()
{
try{
//New Thread for logic();
Thread t1=new Thread(new Runnable() {
public void run() {
// calling your logic function in a new thread
try{login();}catch(Exception e){e.printStackTrace();}
}
});
t1.start();
//Making the current thread to sleep for 8 seconds.
Thread.sleep(8000);
//check if t1 has ended within 8 seconds, and then return the required value
if(!t1.isAlive())
return true;
else
return false;
}
catch(Exception e)
{
e.printStackTrace();
return false;
}
}
void login()throws Exception
{
Thread.sleep(9000);//tweak this value sleeps the t1 thread for a specific time just to simulate the login function
}
// driver method
public static void main(String args[])
{
System.out.println(new Test().doLogic());
}
}
這兩個答案都允許通過重復的登錄請求拒絕服務攻擊。 由於執行線程將在8秒后仍繼續執行,因此觸發重復的登錄嘗試將繼續創建將消耗資源的線程。 CompletableFuture
方法將填滿公共池,該池不會繼續創建線程,但是會影響使用公共池的代碼的所有其他部分。
您可以做的是創建一個具有一個或幾個僅用於登錄的連接的輔助池。將連接簽出超時設置為8秒,然后就可以立即設置超時。 更不用說在執行業務任務的池中減少競爭。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.