天天看點

正确停止線程(四)

1.使用interrupt關閉線程

/**
 * 使用interrupt關閉線程,注意不可強制,而是要判斷true如果目前線程已被中斷; false除此以外。!Thread.currentThread().isInterrupted()
 */
public class RightWayStopThreadWithoutSleep implements Runnable{
    @Override
    public void run() {
        int num = 0;
        while (!Thread.currentThread().isInterrupted() && num<=Integer.MAX_VALUE /2){
            if(num%10000==0){
                System.out.println(num+"是1000的倍數");
            }
            num++;
        }
        System.out.println("結束啦");
    }
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new RightWayStopThreadWithoutSleep());
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
    }
}

      

2.堵塞狀态中斷的方式是抛出異常:

 1.循環裡面使用了Thread.sleep(1000);代表每次運作都延遲1s,最下面的5s是整個線程運作5s然後會抛出異常結束線程

2.循環裡面可以不用Thread.currentThread().isInterrupted()來判斷線程是否要到點關閉了

/**
 * 如果在執行過程中,每次循環都會調用sleep或wait等方法,那麼不需要每次疊代都檢查是否已中斷
 */
public class RightWayStopThreadWithSleepEveryLoop {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = ()->{
            int num = 0;
            try {
            while (num<=10000000){
                if (num%10 ==0){
                    System.out.println(num+"是10的倍數");
                }
                num+=10;
                Thread.sleep(1000);
                System.out.println("hhh");
            }
       } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(5000);
        thread.interrupt();

    }
}      
正确停止線程(四)

3.把try-catch放在while裡面堵塞狀态中斷會失效:

正确停止線程(四)

4.把try-catch放在while裡面堵塞狀态中斷會失效怎麼辦?:1.傳遞中斷

1.這裡try-catch還是在while裡面,最好是在catch裡面做出選擇停止線程,這個demo是把休息時間放在了throwInMethod這個方法裡面,也try-catch了,但是呢

/**
 * 最佳時間 catch了InterruptedEcxetion之後的優先選擇
 * :在方法簽名中抛出異常
 * 那麼在run()就會強制try/catch
 */
public class RightWayStopThreadInProd implements Runnable{
    @Override
    public void run() {
        while (true && !Thread.currentThread().isInterrupted()){
            System.out.println("我來啦");
            new RightWayStopThreadInProd().throwInMethod();
        }
    }
    private void throwInMethod(){
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new RightWayStopThreadInProd());
        thread.start();
        Thread.sleep(5000);
        thread.interrupt();
    }
}

2.這裡try-catch還是在while裡面,最好是在catch裡面做出選擇停止線程,這個demo是把休息時間放在了throwInMethod這個方法裡面,也try-catch了,但是呢try-catch是在使用的地方try-catch的這樣可以根據不同的需求做不同的處理      
/**
 * 最佳時間 catch了InterruptedEcxetion之後的優先選擇
 * :在方法簽名中抛出異常
 * 那麼在run()就會強制try/catch
 */
@Slf4j
public class RightWayStopThreadInProd implements Runnable{
    @Override
    public void run() {
        while (true && !Thread.currentThread().isInterrupted()){
            System.out.println("我來啦");
            try {
                new RightWayStopThreadInProd().throwInMethod();
            } catch (InterruptedException e) {
                log.error("我在這中斷了,我要看我跳出來了之後幹嘛",e.getMessage());
                break;
            }
        }
    }
    private void throwInMethod() throws InterruptedException {
            Thread.sleep(2000);
    }
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new RightWayStopThreadInProd());
        thread.start();
        Thread.sleep(5000);
        thread.interrupt();
    }
}      
正确停止線程(四)

5.把try-catch放在while裡面堵塞狀态中斷會失效怎麼辦?:2.恢複中斷