Heim  >  Artikel  >  Java  >  So schreiben Sie eine Timeout-Tool-Klasse in Java

So schreiben Sie eine Timeout-Tool-Klasse in Java

王林
王林nach vorne
2023-05-04 14:37:061269Durchsuche

1. Beschreibung

Java hat uns eine Lösung geliefert. Die von jdk1.5 bereitgestellte Future-Klasse der Parallelitätsbibliothek kann diese Anforderung erfüllen. Die wichtigen Methoden in der Future-Klasse sind get() und cancel(). get() ruft das Datenobjekt ab, bevor es das Laden der Daten abbricht. Eine andere get(timeout)-Operation zeigt, dass sie fehlschlägt und ohne Blockierung zurückkehrt, wenn sie nicht innerhalb des Timeouts abgerufen wird.

Das Schreiben einer Toolklasse unter Verwendung von Generika und funktionalen Schnittstellen kann die Timeout-Verarbeitung komfortabler machen, ohne dass überall Code geschrieben werden muss.

2. Beispiel

/**
 * TimeoutUtil <br>
 *
 * @author lys
 * @date 2021/2/25
 */
@Slf4j
@Component
@NoArgsConstructor
public class TimeoutUtil {
 
    private ExecutorService executorService;
 
    public TimeoutUtil(ExecutorService executorService) {
        this.executorService = executorService;
    }
 
    /**
     * 有超时限制的方法
     *
     * @param bizSupplier 业务函数
     * @param timeout     超时时间,ms
     * @return 返回值
     */
    public <R> Result<R> doWithTimeLimit(Supplier<R> bizSupplier, int timeout) {
        return doWithTimeLimit(bizSupplier, null, timeout);
    }
 
    /**
     * 有超时限制的方法
     *
     * @param bizSupplier   业务函数
     * @param defaultResult 默认值
     * @param timeout       超时时间,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执行超过%d毫秒,强制结束", timeout);
            log.error(errMsg, e);
            futureTask.cancel(true);
            result = defaultResult;
        }
        return of(result, errMsg);
    }
 
    /**
     * 随机耗时的测试方法
     */
    private String randomSpentTime() {
        Random random = new Random();
        int time = (random.nextInt(10) + 1) * 1000;
        log.info("预计randomSpentTime方法执行将耗时: " + 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);
                    // 以守护线程方式启动
                    thread.setDaemon(true);
                    return thread;
                });
        TimeoutUtil timeoutUtil = new TimeoutUtil(executorService);
        for (int i = 1; i <= 10; i++) {
            log.info("\n=============第{}次超时测试=============", i);
            Thread.sleep(6000);
            long start = System.currentTimeMillis();
            String result = timeoutUtil.doWithTimeLimit(() -> timeoutUtil.randomSpentTime(), 5000).getOrElse("默认");
            log.info("doWithTimeLimit方法实际耗时{}毫秒,结果:{}", System.currentTimeMillis() - start, result);
        }
    }
 
}

Das obige ist der detaillierte Inhalt vonSo schreiben Sie eine Timeout-Tool-Klasse in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen