欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java利用異常中斷當(dāng)前任務(wù)的技巧分享

 更新時間:2023年08月28日 14:05:26   作者:樂征skyline  
在日常開發(fā)中,我們經(jīng)常遇到調(diào)用別人的代碼來完成某個任務(wù),但是當(dāng)代碼比較耗時的時候,沒法從外部終止該任務(wù),所以本文為大家介紹了如何利用異常中斷當(dāng)前任務(wù),需要的可以參考下

Java小技巧:利用異常中斷當(dāng)前任務(wù)

在日常開發(fā)中,我們經(jīng)常遇到調(diào)用別人的代碼來完成某個任務(wù),但是當(dāng)代碼比較耗時的時候,沒法從外部終止該任務(wù)。有些程序從開始就考慮到了這個場景,就會提供對應(yīng)的cancelstop之類的方法用于終止任務(wù),但還是會有很多三方庫并沒有提供響應(yīng)接口。比如,下面這個下載示例:

class DownloadTask {
    public void download(Listener listener) {
        try {
            for (int i = 0; i < 100; i++) {//模擬下載過程
                Thread.sleep(1000);
                listener.onProgressUpdated(i + 1);
            }
            listener.onCompleted();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    public interface Listener {
        void onProgressUpdated(int progress);
        void onCompleted();
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException {
        DownloadTask task = new DownloadTask();
        task.download(new DownloadTask.Listener() {
            @Override
            public void onProgressUpdated(int progress) {
                System.out.println("onProgressUpdated: " + progress);
                if (isInterrupted.get()) {
                    throw new EndException();
                }
            }
            @Override
            public void onCompleted() {
            }
        });
    }
}

這里的DownloadTask開始運行后,就無法直接停止。如果DownloadTask是第三方庫的代碼時,我們可能不方便改它的代碼使其支持中斷。本文介紹一種利用異常來終止這樣的任務(wù)的方法。

(注:本文介紹的方法僅限于單線程或單個子線程的情況,并且需要有在任務(wù)運行的線程執(zhí)行代碼的能力,比如回調(diào))

場景1:任務(wù)沒有另起線程的情況

這個就是上面展示的那個下載示例,我們可以通過回調(diào),直接利用異常中斷該任務(wù):

//DownloadTask 同上
public class Main {
    private static volatile boolean isInterrupted;
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {//模擬外部調(diào)用,5秒后通過設(shè)置isInterrupted來取消任務(wù),也可以把這段代碼放到一個新的cancel方法中
            sleep(5000);
            isInterrupted = true;
        }).start();
        try {
            DownloadTask task = new DownloadTask();
            task.download(new DownloadTask.Listener() {
                @Override
                public void onProgressUpdated(int progress) {
                    System.out.println("onProgressUpdated: " + progress);
                    if (isInterrupted) {
                        throw new EndException();
                    }
                }
                @Override
                public void onCompleted() {
                    System.out.println("onCompleted...");
                }
            });
        }catch (EndException e){
            System.out.println("end...");
            //is interrupted, ignore
        }
        Thread.currentThread().join();
    }
    static class EndException extends RuntimeException {
    }
    public static void sleep(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

場景2:任務(wù)另起子線程的情況

如果任務(wù)另起子線程來執(zhí)行,那么就沒法直接用try-catch來捕獲異常,那么就得通過線程的UncaughtExceptionHandler來完成。假如下載的代碼是這樣的:

public class DownloadTask {
    public void download(Listener listener) {
        new Thread(() -> {
            try {
                for (int i = 0; i < 100; i++) {//模擬下載過程
                    Thread.sleep(1000);
                    listener.onProgressUpdated(i + 1);
                }
                listener.onCompleted();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();
    }
    public interface Listener {
        void onProgressUpdated(int progress);
        void onCompleted();
    }
}

那么外部調(diào)用并終止的代碼就是:

public class Main {
    private static volatile boolean isInterrupted;
    public static void main(String[] args) throws InterruptedException {
        Thread.UncaughtExceptionHandler handler = (t, e) -> {
            if(e instanceof EndException){
                System.out.println("end...");
                //is interrupted, ignore
            }
        };
        DownloadTask task = new DownloadTask();
        task.download(new DownloadTask.Listener() {
            @Override
            public void onProgressUpdated(int progress) {
                System.out.println("onProgressUpdated: " + progress);
                if(Thread.currentThread().getUncaughtExceptionHandler() != handler){//注意這里
                    Thread.currentThread().setUncaughtExceptionHandler(handler);
                }
                if (isInterrupted) {
                    throw new EndException();
                }
            }
            @Override
            public void onCompleted() {
                System.out.println("onCompleted...");
            }
        });
        sleep(5000);
        isInterrupted = true;
        Thread.currentThread().join();
    }
    public static class EndException extends RuntimeException {
    }
    public static void sleep(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

寫在最后

大家也能看到,這并不是什么萬能的方法,甚至有很大局限,但碰到合適的場景還是可以通過簡短的代碼來解決問題。

到此這篇關(guān)于Java利用異常中斷當(dāng)前任務(wù)的技巧分享的文章就介紹到這了,更多相關(guān)Java中斷任務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot項目如何獲取所有的接口

    Springboot項目如何獲取所有的接口

    這篇文章主要介紹了Springboot項目如何獲取所有的接口,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • mybatis plus開發(fā)過程中遇到的問題記錄及解決

    mybatis plus開發(fā)過程中遇到的問題記錄及解決

    這篇文章主要介紹了mybatis plus開發(fā)過程中遇到的問題記錄及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • SpringBoot Event實現(xiàn)異步消費機(jī)制的示例代碼

    SpringBoot Event實現(xiàn)異步消費機(jī)制的示例代碼

    這篇文章主要介紹了SpringBoot Event實現(xiàn)異步消費機(jī)制,ApplicationEvent以及Listener是Spring為我們提供的一個事件監(jiān)聽、訂閱的實現(xiàn),內(nèi)部實現(xiàn)原理是觀察者設(shè)計模式,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2024-04-04
  • 關(guān)于Filter中獲取請求體body后再次讀取的問題

    關(guān)于Filter中獲取請求體body后再次讀取的問題

    這篇文章主要介紹了關(guān)于Filter中獲取請求體body后再次讀取的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java解析xml匯總_動力節(jié)點Java學(xué)院整理

    java解析xml匯總_動力節(jié)點Java學(xué)院整理

    這篇文章主要介紹了java解析xml匯總_動力節(jié)點Java學(xué)院整理的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • Spring?Boot快速過濾出一次請求的所有日志

    Spring?Boot快速過濾出一次請求的所有日志

    這篇文章主要介紹了Spring?Boot快速過濾出一次請求的所有日志,本文講述了如何使用MDC工具來快速過濾一次請求的所有日志,并通過裝飾器模式使得MDC工具在異步線程里也能生效,需要的朋友可以參考下
    2022-11-11
  • Java線程池由淺入深掌握到精通

    Java線程池由淺入深掌握到精通

    什么是線程池?很簡單,簡單看名字就知道是裝有線程的池子,我們可以把要執(zhí)行的多線程交給線程池來處理,和連接池的概念一樣,通過維護(hù)一定數(shù)量的線程池來達(dá)到多個線程的復(fù)用
    2021-09-09
  • Mybatis-Plus 全局配置無效的解決方案

    Mybatis-Plus 全局配置無效的解決方案

    這篇文章主要介紹了Mybatis-Plus 全局配置無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 一文教會你如何搭建vue+springboot項目

    一文教會你如何搭建vue+springboot項目

    最近在搗鼓?SpringBoot?與?Vue?整合的項目,所以下面這篇文章主要給大家介紹了關(guān)于如何通過一篇文章教會你搭建vue+springboot項目,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • Java super關(guān)鍵字用法實戰(zhàn)案例分析

    Java super關(guān)鍵字用法實戰(zhàn)案例分析

    這篇文章主要介紹了Java super關(guān)鍵字用法,結(jié)合具體案例形式分析了java super關(guān)鍵字調(diào)用父類構(gòu)造方法、屬性及方法等相關(guān)操作技巧與注意事項,需要的朋友可以參考下
    2019-09-09

最新評論