最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java程序超時停止的實踐方案

 更新時間:2025年10月29日 14:42:49   作者:今晚噠老虎  
本文探討了多種在Java中控制任務(wù)執(zhí)行時間的方法,分析了不同方案的優(yōu)缺點,介紹了基于時間循環(huán)控制的基礎(chǔ)實現(xiàn)及其局限性,詳細講解了線程中斷機制,感興趣的朋友跟隨小編一起看看吧

1. 概述

在實際開發(fā)中,我們經(jīng)常需要控制任務(wù)的執(zhí)行時間,避免長時間運行的任務(wù)影響系統(tǒng)性能或用戶體驗。本文將深入探討多種在指定時間后停止Java程序執(zhí)行的方法,分析各種方案的優(yōu)缺點,并提供實用的代碼示例。

2. 基于時間循環(huán)控制

基礎(chǔ)實現(xiàn)原理

public class TimeLoopExample {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        long timeoutMs = 30 * 1000; // 30秒超時
        long endTime = startTime + timeoutMs;
        while (System.currentTimeMillis() < endTime) {
            // 執(zhí)行耗時操作
            performTimeConsumingTask();
            // 每次循環(huán)后檢查時間,確保及時退出
            if (System.currentTimeMillis() >= endTime) {
                break;
            }
        }
        System.out.println("任務(wù)執(zhí)行完成或已超時");
    }
    private static void performTimeConsumingTask() {
        try {
            // 模擬耗時操作
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

方案優(yōu)缺點分析

優(yōu)點:

  • 實現(xiàn)簡單,代碼直觀
  • 不需要額外的線程管理

缺點:

  • 時間精度不足:循環(huán)實際執(zhí)行時間可能遠超設(shè)定閾值
  • 阻塞主線程:長時間運行會阻塞主線程執(zhí)行
  • 資源浪費:無法充分利用多核CPU優(yōu)勢

3. 線程中斷機制

可中斷任務(wù)設(shè)計

public class InterruptibleTask implements Runnable {
    private volatile boolean running = true;
    @Override
    public void run() {
        try {
            while (running && !Thread.currentThread().isInterrupted()) {
                // 檢查中斷狀態(tài)并執(zhí)行任務(wù)
                performTask();
                // 對于不可中斷的阻塞操作,需要手動檢查狀態(tài)
                if (Thread.currentThread().isInterrupted()) {
                    break;
                }
            }
        } finally {
            cleanup();
        }
    }
    private void performTask() {
        try {
            // 可中斷的阻塞操作
            Thread.sleep(500);
            System.out.println("任務(wù)執(zhí)行中..." + System.currentTimeMillis());
        } catch (InterruptedException e) {
            // 恢復中斷狀態(tài)并退出
            Thread.currentThread().interrupt();
            running = false;
        }
    }
    private void cleanup() {
        System.out.println("執(zhí)行資源清理操作");
    }
    public void stop() {
        running = false;
    }
}

3.1 使用Timer實現(xiàn)超時控制

public class TimerTimeoutExample {
    public static void main(String[] args) {
        Thread workerThread = new Thread(new InterruptibleTask());
        Timer timer = new Timer(true); // 守護線程定時器
        TimerTask timeoutTask = new TimerTask() {
            @Override
            public void run() {
                if (workerThread.isAlive()) {
                    System.out.println("超時中斷工作線程");
                    workerThread.interrupt();
                }
                this.cancel(); // 取消定時任務(wù)
            }
        };
        // 30秒后執(zhí)行中斷
        timer.schedule(timeoutTask, 30000);
        workerThread.start();
        try {
            workerThread.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

3.2 使用Future.get()實現(xiàn)超時

public class FutureTimeoutExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        try {
            Future<?> future = executor.submit(new InterruptibleTask());
            try {
                // 設(shè)置30秒超時
                future.get(30, TimeUnit.SECONDS);
                System.out.println("任務(wù)正常完成");
            } catch (TimeoutException e) {
                System.out.println("任務(wù)執(zhí)行超時,嘗試取消");
                future.cancel(true); // 中斷線程
            } catch (Exception e) {
                System.out.println("任務(wù)執(zhí)行異常: " + e.getMessage());
            }
        } finally {
            executor.shutdown();
        }
    }
}

3.3 使用ScheduledExecutorService(推薦)

public class ScheduledExecutorExample {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
        ExecutorService workerExecutor = Executors.newSingleThreadExecutor();
        try {
            Future<?> future = workerExecutor.submit(new InterruptibleTask());
            // 安排30秒后取消任務(wù)
            scheduler.schedule(() -> {
                if (!future.isDone()) {
                    System.out.println("執(zhí)行超時,取消任務(wù)");
                    future.cancel(true);
                }
            }, 30, TimeUnit.SECONDS);
            // 等待任務(wù)完成
            try {
                future.get();
            } catch (CancellationException e) {
                System.out.println("任務(wù)已被取消");
            } catch (Exception e) {
                System.out.println("任務(wù)執(zhí)行異常: " + e.getMessage());
            }
        } finally {
            workerExecutor.shutdown();
            scheduler.shutdown();
        }
    }
}

4. 高級超時控制模式

4.1 組合式超時控制

public class CompositeTimeoutController {
    private final ExecutorService executor;
    private final ScheduledExecutorService scheduler;
    public CompositeTimeoutController() {
        this.executor = Executors.newCachedThreadPool();
        this.scheduler = Executors.newScheduledThreadPool(1);
    }
    public <T> T executeWithTimeout(Callable<T> task, long timeout, TimeUnit unit) 
            throws Exception {
        Future<T> future = executor.submit(task);
        // 設(shè)置超時取消
        scheduler.schedule(() -> {
            if (!future.isDone()) {
                future.cancel(true);
            }
        }, timeout, unit);
        try {
            return future.get();
        } catch (CancellationException e) {
            throw new TimeoutException("任務(wù)執(zhí)行超時");
        }
    }
    public void shutdown() {
        executor.shutdown();
        scheduler.shutdown();
    }
}

4.2 可配置的超時任務(wù)包裝器

public class TimeoutTaskWrapper {
    public static Runnable wrapWithTimeout(Runnable task, long timeout, TimeUnit unit) {
        return () -> {
            Thread workerThread = Thread.currentThread();
            ScheduledExecutorService timeoutExecutor = 
                Executors.newSingleThreadScheduledExecutor();
            // 設(shè)置超時中斷
            ScheduledFuture<?> timeoutFuture = timeoutExecutor.schedule(() -> {
                if (!workerThread.isInterrupted()) {
                    workerThread.interrupt();
                }
            }, timeout, unit);
            try {
                task.run();
            } finally {
                timeoutFuture.cancel(false);
                timeoutExecutor.shutdown();
            }
        };
    }
}

5. 中斷機制的局限性及應(yīng)對策略

5.1 不可中斷的阻塞操作

public class NonInterruptibleHandler {
    private volatile boolean stopped = false;
    public void handleWithCustomInterrupt() {
        while (!stopped && !Thread.currentThread().isInterrupted()) {
            try {
                // 模擬不可中斷的I/O操作
                performNonInterruptibleIO();
                // 定期檢查停止標志
                if (stopped || Thread.currentThread().isInterrupted()) {
                    break;
                }
            } catch (Exception e) {
                if (!stopped) {
                    // 處理異常但不停止
                    System.err.println("處理IO異常: " + e.getMessage());
                }
            }
        }
    }
    private void performNonInterruptibleIO() {
        // 使用NIO或者設(shè)置socket超時來避免永久阻塞
        // BufferedReader.read() 是不可中斷的
    }
    public void stop() {
        stopped = true;
    }
}

5.2 使用Java NIO實現(xiàn)可中斷I/O

public class InterruptibleNIOExample {
    public void readWithTimeout(Path filePath, long timeout, TimeUnit unit) 
            throws IOException {
        try (AsynchronousFileChannel channel = 
                AsynchronousFileChannel.open(filePath, StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            Future<Integer> readResult = channel.read(buffer, 0);
            try {
                Integer bytesRead = readResult.get(timeout, unit);
                processData(buffer, bytesRead);
            } catch (TimeoutException e) {
                readResult.cancel(true);
                throw new IOException("讀取操作超時");
            }
        }
    }
    private void processData(ByteBuffer buffer, int bytesRead) {
        // 處理讀取的數(shù)據(jù)
    }
}

6. 最佳實踐總結(jié)

6.1 方案選擇建議

場景推薦方案理由
簡單循環(huán)任務(wù)時間循環(huán)檢查實現(xiàn)簡單,適合不嚴格的超時控制
需要精確控制ScheduledExecutorService功能強大,靈活性高
I/O密集型任務(wù)Future + 超時設(shè)置天然支持異步I/O超時
復雜業(yè)務(wù)邏輯自定義中斷標志提供更細粒度的控制

6.2 重要注意事項

  1. 及時資源清理:確保在任務(wù)停止后釋放所有占用的資源
  2. 狀態(tài)一致性:中斷操作不應(yīng)導致數(shù)據(jù)處于不一致狀態(tài)
  3. 優(yōu)雅降級:提供超時后的降級處理方案
  4. 日志記錄:詳細記錄超時發(fā)生時的上下文信息

6.3 完整示例:生產(chǎn)級超時控制器

public class ProductionTimeoutManager {
    private final ScheduledExecutorService scheduler;
    private final Map<Future<?>, ScheduledFuture<?>> timeoutMap;
    public ProductionTimeoutManager() {
        this.scheduler = Executors.newScheduledThreadPool(2);
        this.timeoutMap = new ConcurrentHashMap<>();
    }
    public <T> Future<T> submitWithTimeout(Callable<T> task, 
                                         long timeout, 
                                         TimeUnit unit,
                                         Runnable timeoutCallback) {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<T> future = executor.submit(task);
        ScheduledFuture<?> timeoutFuture = scheduler.schedule(() -> {
            if (!future.isDone()) {
                future.cancel(true);
                if (timeoutCallback != null) {
                    timeoutCallback.run();
                }
                timeoutMap.remove(future);
            }
        }, timeout, unit);
        timeoutMap.put(future, timeoutFuture);
        // 任務(wù)完成時清理超時控制
        scheduler.execute(() -> {
            try {
                future.get();
            } catch (Exception e) {
                // 忽略異常,主要是為了觸發(fā)完成狀態(tài)
            } finally {
                ScheduledFuture<?> scheduledFuture = timeoutMap.remove(future);
                if (scheduledFuture != null) {
                    scheduledFuture.cancel(false);
                }
                executor.shutdown();
            }
        });
        return future;
    }
    public void shutdown() {
        scheduler.shutdown();
    }
}

通過本文介紹的各種方法,您可以根據(jù)具體場景選擇最適合的超時控制方案。在實際項目中,建議優(yōu)先使用ScheduledExecutorServiceFuture組合的方式,它們提供了最好的靈活性和可靠性。

到此這篇關(guān)于Java程序超時停止的完整指南的文章就介紹到這了,更多相關(guān)java超時停止內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文了解Seata的實現(xiàn)原理

    一文了解Seata的實現(xiàn)原理

    隨著業(yè)務(wù)發(fā)展,單體系統(tǒng)逐漸無法滿足業(yè)務(wù)的需求,分布式架構(gòu)逐漸成為大型互聯(lián)網(wǎng)平臺首選。伴隨而來的問題是,本地事務(wù)方案已經(jīng)無法滿足,分布式事務(wù)相關(guān)規(guī)范和框架應(yīng)運而生。本文主要介紹Seata的實現(xiàn)原理
    2021-06-06
  • springboot prototype設(shè)置多例不起作用的解決操作

    springboot prototype設(shè)置多例不起作用的解決操作

    這篇文章主要介紹了springboot prototype設(shè)置多例不起作用的解決操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • java 代理機制的實例詳解

    java 代理機制的實例詳解

    這篇文章主要介紹了java 代理機制的實例詳解的相關(guān)資料,這里說明下如何實現(xiàn)代理機制,幫助大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • Java結(jié)構(gòu)型模式之代理模式詳解

    Java結(jié)構(gòu)型模式之代理模式詳解

    這篇文章主要介紹了Java結(jié)構(gòu)型模式之代理模式,代理模式是常用的java設(shè)計模式,他的特征是代理類與委托類有同樣的接口,代理類主要負責為委托類預(yù)處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等
    2023-02-02
  • 關(guān)于swagger配置及踩坑@Api參數(shù)postion無效解決接口排序問題

    關(guān)于swagger配置及踩坑@Api參數(shù)postion無效解決接口排序問題

    這篇文章主要介紹了關(guān)于swagger配置及踩坑@Api參數(shù)postion無效解決接口排序問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • spring?boot2升級spring?boot3的整體步驟流程

    spring?boot2升級spring?boot3的整體步驟流程

    從Spring Boot2到Spring Boot3的升級是一次全面而深刻的變革,它不僅帶來了技術(shù)棧的更新和新特性的引入,還顯著提升了應(yīng)用的性能和開發(fā)效率,這篇文章主要給大家介紹了關(guān)于spring?boot2升級spring?boot3的整體步驟,需要的朋友可以參考下
    2025-08-08
  • Spring boot 連接多數(shù)據(jù)源過程詳解

    Spring boot 連接多數(shù)據(jù)源過程詳解

    這篇文章主要介紹了Spring boot 連接多數(shù)據(jù)源過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • 基于mybatis查詢結(jié)果映射不到對象的處理

    基于mybatis查詢結(jié)果映射不到對象的處理

    這篇文章主要介紹了mybatis查詢結(jié)果映射不到對象的處理方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot/Spring?AOP默認動態(tài)代理方式實例詳解

    SpringBoot/Spring?AOP默認動態(tài)代理方式實例詳解

    這篇文章主要給大家介紹了關(guān)于SpringBoot/Spring?AOP默認動態(tài)代理方式的相關(guān)資料,Spring AOP是一款基于Java的AOP框架,其中默認采用動態(tài)代理方式實現(xiàn)AOP功能,本文將詳細介紹動態(tài)代理的實現(xiàn)原理和使用方法,需要的朋友可以參考下
    2023-03-03
  • Java序列化常見的三個問題

    Java序列化常見的三個問題

    這篇文章主要介紹了Java序列化常見的三個問題,幫助大家更好的理解和學習JAVA,感興趣的朋友可以了解下
    2020-08-08

最新評論

根河市| 文山县| 宣汉县| 通许县| 天等县| 洞口县| 东源县| 江达县| 岳阳市| 嘉兴市| 沧源| 井陉县| 乃东县| 青铜峡市| 洪洞县| 横山县| 金塔县| 金乡县| 辰溪县| 调兵山市| 育儿| 桂平市| 临湘市| 乌鲁木齐县| 锡林郭勒盟| 大英县| 嫩江县| 元阳县| 壶关县| 遂平县| 甘谷县| 阿拉善盟| 望谟县| 凌源市| 开封市| 宜川县| 封丘县| 呼和浩特市| 洛阳市| 三亚市| 旬阳县|