Java編寫超時(shí)工具類實(shí)例講解
我們?cè)陂_發(fā)過程中,在進(jìn)行時(shí)間操作時(shí),如果在規(guī)定的時(shí)間內(nèi)完成處理的話,有可能會(huì)回到正確的結(jié)果。否則,就會(huì)被視為超時(shí)任務(wù)。此時(shí),我們不再等待(不再執(zhí)行)的時(shí)間操作,直接向調(diào)用者傳達(dá)這個(gè)任務(wù)需要時(shí)間,被取消了。
1、說明
java已經(jīng)為我們提供了解決辦法。jdk1.5帶來的并發(fā)庫Future類可以滿足這一需求。Future類中重要的方法有g(shù)et()和cancel()。get()獲取數(shù)據(jù)對(duì)象,如果數(shù)據(jù)沒有加載,則在獲取數(shù)據(jù)之前堵塞,cancel()取消數(shù)據(jù)加載。另一個(gè)get(timeout)操作表明,如果timeout時(shí)間內(nèi)沒有得到,就會(huì)失敗回來,不會(huì)堵塞。
利用泛型和函數(shù)式接口編寫一個(gè)工具類,可以讓超時(shí)處理更方便,而不用到處寫代碼。
2、實(shí)例
/**
* TimeoutUtil <br>
*
* @author lys
* @date 2021/2/25
*/
@Slf4j
@Component
@NoArgsConstructor
public class TimeoutUtil {
private ExecutorService executorService;
public TimeoutUtil(ExecutorService executorService) {
this.executorService = executorService;
}
/**
* 有超時(shí)限制的方法
*
* @param bizSupplier 業(yè)務(wù)函數(shù)
* @param timeout 超時(shí)時(shí)間,ms
* @return 返回值
*/
public <R> Result<R> doWithTimeLimit(Supplier<R> bizSupplier, int timeout) {
return doWithTimeLimit(bizSupplier, null, timeout);
}
/**
* 有超時(shí)限制的方法
*
* @param bizSupplier 業(yè)務(wù)函數(shù)
* @param defaultResult 默認(rèn)值
* @param timeout 超時(shí)時(shí)間,ms
* @return 返回值
*/
public <R> Result<R> doWithTimeLimit(Supplier<R> bizSupplier, R defaultResult, int timeout) {
R result;
String errMsg = "Null value";
FutureTask<R> futureTask = new FutureTask<>(bizSupplier::get);
executorService.execute(futureTask);
try {
result = futureTask.get(timeout, TimeUnit.MILLISECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
errMsg = String.format("doWithTimeLimit執(zhí)行超過%d毫秒,強(qiáng)制結(jié)束", timeout);
log.error(errMsg, e);
futureTask.cancel(true);
result = defaultResult;
}
return of(result, errMsg);
}
/**
* 隨機(jī)耗時(shí)的測(cè)試方法
*/
private String randomSpentTime() {
Random random = new Random();
int time = (random.nextInt(10) + 1) * 1000;
log.info("預(yù)計(jì)randomSpentTime方法執(zhí)行將耗時(shí): " + time + "毫秒");
try {
Thread.sleep(time);
} catch (Exception e) {
}
return "randomSpentTime --> " + time;
}
public static void main(String[] args) throws Exception {
ExecutorService executorService = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
runnable -> {
Thread thread = new Thread(runnable);
// 以守護(hù)線程方式啟動(dòng)
thread.setDaemon(true);
return thread;
});
TimeoutUtil timeoutUtil = new TimeoutUtil(executorService);
for (int i = 1; i <= 10; i++) {
log.info("\n=============第{}次超時(shí)測(cè)試=============", i);
Thread.sleep(6000);
long start = System.currentTimeMillis();
String result = timeoutUtil.doWithTimeLimit(() -> timeoutUtil.randomSpentTime(), 5000).getOrElse("默認(rèn)");
log.info("doWithTimeLimit方法實(shí)際耗時(shí){}毫秒,結(jié)果:{}", System.currentTimeMillis() - start, result);
}
}
}
實(shí)例知識(shí)點(diǎn)擴(kuò)展:
屬性校驗(yàn)工具類
/**
* 校驗(yàn)對(duì)象中的屬性。如果屬性為null,拋異常。如果屬性為字符串(空串或空格),拋異常。
* @author mex
* @date 2019年4月18日
* @param e 對(duì)象
* @param fieldNames 屬性名稱數(shù)組
* @return void
* @throws Exception
*/
public static <E> void validateAttr(E e, String[] fieldNames) throws Exception {
if (null == e) {
throw new Exception("請(qǐng)求對(duì)象為空");
}
if (null == fieldNames) {
return;
}
for (int i = 0; i < fieldNames.length; i++) {
String fieldName = fieldNames[i];
Field field = e.getClass().getDeclaredField(fieldName);
String typeName = field.getGenericType().getTypeName();
field.setAccessible(Boolean.TRUE);
Object fieldValue = field.get(e);
// 判斷該屬性為null的情況
if (null == fieldValue) {
throw new Exception("請(qǐng)求字段:" + fieldName + "不能為空");
}
// 如果該屬性為字符串,判斷其為空或空格的情況
if ("java.lang.String".equals(typeName)) {
if (StringUtils.isBlank((String)fieldValue)) {
throw new Exception("請(qǐng)求字段:" + fieldName + "不能為空");
}
}
}
}
到此這篇關(guān)于Java編寫超時(shí)工具類實(shí)例講解的文章就介紹到這了,更多相關(guān)Java編寫超時(shí)工具類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 教你如何使用Java多線程編程LockSupport工具類
- Java常用工具類庫——Hutool的使用簡介
- 淺談java如何生成分享海報(bào)工具類
- java中封裝JDBC工具類的實(shí)例分析
- Java JDBC自定義封裝工具類的步驟和完整代碼
- java中金額元轉(zhuǎn)萬元工具類的實(shí)例
- Java利用POI讀寫Excel文件工具類
- java讀取簡單excel通用工具類
- Java身份證號(hào)碼校驗(yàn)工具類詳解
- java處理日期的工具類DateUtil
- java身份證合法性校驗(yàn)工具類實(shí)例代碼
- Java實(shí)現(xiàn)RSA加密工具類
- Java基礎(chǔ)之顏色工具類(超詳細(xì)注釋)
相關(guān)文章
mybatis設(shè)置sql執(zhí)行時(shí)間超時(shí)時(shí)間的方法
本文主要介紹了mybatis設(shè)置sql執(zhí)行時(shí)間超時(shí)時(shí)間的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
Java實(shí)現(xiàn)ATM銀行管理系統(tǒng)(控制臺(tái)版本)
這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實(shí)現(xiàn)控制臺(tái)版本的ATM銀行管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
Java Swing中JList選擇事件監(jiān)聽器ListSelectionListener用法示例
這篇文章主要介紹了Java Swing中JList選擇事件監(jiān)聽器ListSelectionListener用法,結(jié)合具體實(shí)例形式分析了中JList選擇事件監(jiān)聽器ListSelectionListener的功能、使用方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-11-11
maven自動(dòng)將源碼打包并發(fā)布的實(shí)現(xiàn)步驟
maven-source-plugin 提供項(xiàng)目自動(dòng)將源碼打包并發(fā)布的功能,在需要發(fā)布源碼項(xiàng)目的 pom.xml 文件中添加即可,本文就來介紹一下如何設(shè)置,感興趣的可以了解一下2023-11-11
Java中Prime算法的原理與實(shí)現(xiàn)詳解
Prime算法是一種窮舉查找算法來從一個(gè)連通圖中構(gòu)造一棵最小生成樹。本文主要為大家介紹了Java中Prime算法的原理與實(shí)現(xiàn),感興趣的可以學(xué)習(xí)一下2022-07-07
使用JPA雙向多對(duì)多關(guān)聯(lián)關(guān)系@ManyToMany
這篇文章主要介紹了使用JPA雙向多對(duì)多關(guān)聯(lián)關(guān)系@ManyToMany,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
Spring中的@EnableScheduling定時(shí)任務(wù)注解
這篇文章主要介紹了Spring中的@EnableScheduling注解,@EnableScheduling是 Spring Framework 提供的一個(gè)注解,用于啟用 Spring 的定時(shí)任務(wù)功能,通過使用這個(gè)注解,可以在 Spring 應(yīng)用程序中創(chuàng)建定時(shí)任務(wù),需要的朋友可以參考下2024-01-01
mybatis插件優(yōu)雅實(shí)現(xiàn)字段加密的示例代碼
在很多時(shí)候,我們都需要字段加密,比如郵箱,密碼,電話號(hào)碼等,本文主要介紹了mybatis插件優(yōu)雅實(shí)現(xiàn)字段加密的示例代碼,感興趣的可以了解一下2023-11-11
Spring cloud Feign 深度學(xué)習(xí)與應(yīng)用詳解
這篇文章主要介紹了Spring cloud Feign 深度學(xué)習(xí)與應(yīng)用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-06-06

