Java實(shí)現(xiàn)任務(wù)超時(shí)處理方法
任務(wù)超時(shí)處理是比較常見(jiàn)的需求,比如在進(jìn)行一些比較耗時(shí)的操作(如網(wǎng)絡(luò)請(qǐng)求)或者在占用一些比較寶貴的資源(如數(shù)據(jù)庫(kù)連接)時(shí),我們通常需要給這些操作設(shè)置一個(gè)超時(shí)時(shí)間,當(dāng)執(zhí)行時(shí)長(zhǎng)超過(guò)設(shè)置的閾值的時(shí)候,就終止操作并回收資源。Java中對(duì)超時(shí)任務(wù)的處理有兩種方式:一種是基于異步任務(wù)結(jié)果的超時(shí)獲取,一種則是使用延時(shí)任務(wù)來(lái)終止超時(shí)操作。下文將詳細(xì)說(shuō)明。
一、基于異步任務(wù)結(jié)果的超時(shí)獲取
基于異步任務(wù)結(jié)果的獲取通常是跟線程池一起使用的,我們向線程池提交任務(wù)時(shí)會(huì)返回一個(gè)Future對(duì)象,在調(diào)用Future的get方法時(shí),可以設(shè)置一個(gè)超時(shí)時(shí)間,如果超過(guò)設(shè)置的時(shí)間任務(wù)還沒(méi)結(jié)束,就拋出異常。接下來(lái)看代碼:
public class FutureDemo { static ExecutorService executorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2); public static void main(String[] args) { Future<String> future = executorService.submit(new Callable<String>() { @Override public String call() { try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { System.out.println("任務(wù)被中斷。"); } return "OK"; } }); try { String result = future.get(2, TimeUnit.SECONDS); } catch (InterruptedException |ExecutionException | TimeoutException e) { future.cancel(true); System.out.println("任務(wù)超時(shí)。"); }finally { System.out.println("清理資源。"); } }}
運(yùn)行代碼,輸出如下:
二、使用延時(shí)任務(wù)來(lái)終止超時(shí)操作
還有一種實(shí)現(xiàn)任務(wù)超時(shí)處理的思路是在提交任務(wù)之前先設(shè)置一個(gè)定時(shí)器,這個(gè)定時(shí)器會(huì)在設(shè)置的時(shí)間間隔之后去取消任務(wù)。當(dāng)然如果任務(wù)在規(guī)定的時(shí)間內(nèi)完成了,要記得取消定時(shí)器。首先來(lái)看一下我們的工作線程:
public class RunningTask { private volatile boolean isStop; public void stop(){ this.isStop=true; } public void doing() { int i=1; while (!isStop){ try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { } } System.out.println("任務(wù)被中斷。"); } }
這個(gè)工作線程每隔一秒鐘會(huì)去檢查下isStop變量,因此我們可以通過(guò)isStop變量來(lái)取消任務(wù)。至于取消任務(wù)的邏輯我們放在了定時(shí)器里面,代碼如下:
public class CancelTask implements Runnable { private RunningTask runningTask; public CancelTask(RunningTask runningTask) { this.runningTask = runningTask; } @Override public void run() { runningTask.stop(); } }
可以看到,該定時(shí)器的作用就是在一定的時(shí)間之后去中斷工作線程的運(yùn)行。接下來(lái)測(cè)試一下:
public class ScheduleDemo { static ScheduledExecutorService executorService= Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors()*2); public static void main(String[] args) { RunningTask runningTask=new RunningTask(); ScheduledFuture<?> scheduledFuture = executorService.schedule(new CancelTask(runningTask), 3, TimeUnit.SECONDS); runningTask.doing(); if(!scheduledFuture.isDone()){ scheduledFuture.cancel(true); } } }
運(yùn)行結(jié)果如下:
可以看到,任務(wù)在超時(shí)之后也可以被取消。
總結(jié)
以上所述是小編給大家介紹的Java實(shí)現(xiàn)任務(wù)超時(shí)處理方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
Java實(shí)現(xiàn)最小生成樹MST的兩種解法
最小生成樹(MST)指在連通圖的所有生成樹中,所有邊的權(quán)值和最小的生成樹。本文介紹了求最小生成樹的兩種方法:Prim算法和Kruskal算法,需要的可以參考一下2022-05-05JAVAEE項(xiàng)目結(jié)構(gòu)以及并發(fā)隨想
每個(gè)代碼里面的工具都是工具,API是你最需要理解的,哪個(gè)好,哪個(gè)不好,沒(méi)有準(zhǔn)確答案。 一切皆對(duì)象,對(duì)于Java來(lái)講是純粹的,代理是對(duì)象,反射是對(duì)象,對(duì)象是對(duì)象,基本數(shù)據(jù)類型不是對(duì)象。2016-04-04SpringBoot使用JTA實(shí)現(xiàn)對(duì)多數(shù)據(jù)源的事務(wù)管理
了解事務(wù)的都知道,在我們?nèi)粘i_發(fā)中單單靠事務(wù)管理就可以解決絕大多數(shù)問(wèn)題了,但是為啥還要提出JTA這個(gè)玩意呢,到底JTA是什么呢?他又是具體來(lái)解決啥問(wèn)題的呢?本文小編就給大家介紹一下如何在Spring Boot中使用JTA實(shí)現(xiàn)對(duì)多數(shù)據(jù)源的事務(wù)管理2023-11-11Jpa數(shù)據(jù)操作以及@Query和@Modifying注解使用方式
這篇文章主要介紹了Jpa數(shù)據(jù)操作以及@Query和@Modifying注解使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07Java二分法查找_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java二分法查找的相關(guān)資料,需要的朋友可以參考下2017-04-04如何在SpringBoot中添加攔截器忽略請(qǐng)求URL當(dāng)中的指定字符串
這篇文章主要介紹了在SpringBoot中添加攔截器忽略請(qǐng)求URL當(dāng)中的指定字符串,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08