07_线程停止(interrupt,interrupted,isInterrupted)

本文详细介绍了Java中线程的启动方式,包括通过继承Thread类和实现Runnable接口两种方法,并深入探讨了线程的停止机制,如使用interrupt()方法、异常法、sleep()方法等不同的停止策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >





一. 线程启动




线程启动

1. 继承 Thread 运行线程 : 重写 Thread 类的 run 方法, 然后执行该线程;

2. 实现 Runnable 接口, 并运行线程;

代码示例

  1. package com.hanshuliang.thread;  
  2.   
  3. public class ThreadStart {  
  4.   
  5.     public static void main(String[] args) {  
  6.         //1. 继承 Thread 运行线程  
  7.         MyThread thread = new MyThread();  
  8.         thread.start();  
  9.           
  10.         //2. 实现 Runnable 接口, 并运行线程  
  11.         Thread runnableThread = new Thread(new MyRunnable());  
  12.         runnableThread.start();  
  13.     }  
  14.       
  15.     //1. 继承 Thread 类  
  16.     static class MyThread extends Thread{  
  17.         @Override  
  18.         public void run() {  
  19.             super.run();  
  20.             System.out.println(”MyThread 线程启动”);  
  21.         }  
  22.     }  
  23.       
  24.     //2. 实现 Runnable 接口  
  25.     static class MyRunnable implements Runnable{  
  26.         @Override  
  27.         public void run() {  
  28.             System.out.println(”MyRunnable 线程启动”);  
  29.         }  
  30.     }  
  31. }  
package com.hanshuliang.thread;

public class ThreadStart {

    public static void main(String[] args) {
        //1. 继承 Thread 运行线程
        MyThread thread = new MyThread();
        thread.start();

        //2. 实现 Runnable 接口, 并运行线程
        Thread runnableThread = new Thread(new MyRunnable());
        runnableThread.start();
    }

    //1. 继承 Thread 类
    static class MyThread extends Thread{
        @Override
        public void run() {
            super.run();
            System.out.println("MyThread 线程启动");
        }
    }

    //2. 实现 Runnable 接口
    static class MyRunnable implements Runnable{
        @Override
        public void run() {
            System.out.println("MyRunnable 线程启动");
        }
    }
}


运行结果

  1. MyThread 线程启动  
  2. MyRunnable 线程启动  
MyThread 线程启动
MyRunnable 线程启动




三. 线程停止



线程停止常用方法

1. 使用 interrupt() 方法停止线程;

2. 使用退出标志, 让线程正常退出;

3. 弃用的方法 (不推荐) : 使用 stop() 方法强制停止线程, 但是该方法已经作废, 不建议使用;


1. 使用 interrupt() 方法停止线程



(1) 线程无法立即停止



interrupt() 使用说明

打标记 : 调用该方法, 不能马上停止该线程, 只是在当前线程打了一个停止标记;


代码示例

代码

  1. public class InterruptDemo {  
  2.     public static class MyThread extends Thread {  
  3.         @Override  
  4.         public void run() {  
  5.             super.run();  
  6.             for (int i = 1; i <= 1000000; i++)   //打印 一百万 数字, 大概持续 5 ~ 10 秒左右  
  7.                 System.out.println(i);  
  8.         }  
  9.     }  
  10.     public static void main(String[] args) throws InterruptedException {  
  11.         MyThread thread = new MyThread();  
  12.         thread.start();                     //启动线程  
  13.         Thread.sleep(100);                  //启动线程 100ms 后中断线程  
  14.         thread.interrupt();                 //中断线程  
  15.     }  
  16. }  
public class InterruptDemo {
    public static class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            for (int i = 1; i <= 1000000; i++)   //打印 一百万 数字, 大概持续 5 ~ 10 秒左右
                System.out.println(i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();
        thread.start();                     //启动线程
        Thread.sleep(100);                  //启动线程 100ms 后中断线程
        thread.interrupt();                 //中断线程
    }
}


运行结果 : 这里只贴上最后几行 命令行的运行结果;

  1. … …  
  2. 999996  
  3. 999997  
  4. 999998  
  5. 999999  
  6. 1000000  
... ...
999996
999997
999998
999999
1000000


总结 : 在上述程序中, 打印了 100 万数字, 从 1 到 100 0000, 整个过程持续了 10秒左右, 但是我们在 线程开始后 100ms 就中断了线程, 但是线程还是执行完毕了, 说明线程并没有在调用 interrupt() 方法后立即停止;




(2) 线程停止状态判定



两个线程停止状态判定的方法

1. interrupted() 方法 : ①判断当前线程的中断标志, ②如果是中断标志 true, 那么清除中断标志, 改为 false;,③ 连续两次调用该方法, 第二次返回 false, ④ 静态方法 : 该方法是测试当前线程的中断标志, 在哪个线程中调用, 就是判定的哪个线程的中断标志, 不管调用的主体是哪个线程;

2. isInterrupted() 方法 : 判断线程的 中断状态, 不管真实的运行状态, 只关心状态;

注意 : 两个方法都是判断 中断状态的, 与线程的真实运行状况无关;



(3) interrupted() 方法测试



interrupted () 方法测试1 : 测试 interrupted 方法的判断是否已经中断的效果;

测试代码

  1. public class InterruptedDemo1 {  
  2.     public static class MyThread extends Thread {  
  3.         @Override  
  4.         public void run() {  
  5.             super.run();  
  6.             for (int i = 1; i <= 10; i++)    //打印10个数字  
  7.                 System.out.println(i);  
  8.         }  
  9.     }  
  10.     public static void main(String[] args) throws InterruptedException {  
  11.         MyThread thread = new MyThread();  
  12.         thread.start();                     //启动线程  
  13.         thread.interrupt();                 //启动线程后马上 中断线程  
  14.           
  15.         System.out.println(”第一次 : thread.interrupted() = ” + thread.interrupted());  
  16.         System.out.println(”第二次 : thread.interrupted() = ” + thread.interrupted());  
  17.     }  
  18. }  
public class InterruptedDemo1 {
    public static class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            for (int i = 1; i <= 10; i++)    //打印10个数字
                System.out.println(i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();
        thread.start();                     //启动线程
        thread.interrupt();                 //启动线程后马上 中断线程

        System.out.println("第一次 : thread.interrupted() = " + thread.interrupted());
        System.out.println("第二次 : thread.interrupted() = " + thread.interrupted());
    }
}


执行结果

  1. 第一次 : thread.interrupted() = false  
  2. 1  
  3. 2  
  4. 第二次 : thread.interrupted() = false  
  5. 3  
  6. 4  
  7. 5  
  8. 6  
  9. 7  
  10. 8  
  11. 9  
  12. 10  
第一次 : thread.interrupted() = false
1
2
第二次 : thread.interrupted() = false
3
4
5
6
7
8
9
10


总结 : 启动线程后, 立即调用 interrupt 方法 中断线程, 但是 在主线程中 调用 thread.Interrupted() 方法, 打印出来的是 主线程的中断状态标志, 虽然是调用的 thread 子线程的对象的方法, 但是该方法是一个静态方法, 在哪个线程调用, 就是打印哪个线程的中断标志;



interrupted () 方法测试2 : 测试 interrupted 方法的 清除 中断状态 的效果;

1. 测试代码

  1. public class InterruptedDemo {  
  2.     public static void main(String[] args) throws InterruptedException {  
  3.         Thread.currentThread().interrupt();     //中断主线程  
  4.           
  5.         System.out.println(”第一次 : thread.interrupted() = ” + Thread.interrupted());  
  6.         System.out.println(”第二次 : thread.interrupted() = ” + Thread.interrupted());  
  7.     }  
  8. }  
public class InterruptedDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread.currentThread().interrupt();     //中断主线程

        System.out.println("第一次 : thread.interrupted() = " + Thread.interrupted());
        System.out.println("第二次 : thread.interrupted() = " + Thread.interrupted());
    }
}


2. 执行结果

  1. 第一次 : thread.interrupted() = true  
  2. 第二次 : thread.interrupted() = false  
第一次 : thread.interrupted() = true
第二次 : thread.interrupted() = false


3. 总结 : 使用 interrupted() 方法, 如果当前线程的状态是中断状态, 即返回了 true, 那么需要清除该标志, 下一次调用 interrupted() 方法后, 返回值就是 false 了;



(4) isInterrupted() 方法测试



isInterrupted() 方法测试1 : 测试其 中断状态, 与上面的 interrupted() 方法对比;

1. 测试代码

  1. public class IsInterruptedDemo {  
  2.     public static class MyThread extends Thread {  
  3.         @Override  
  4.         public void run() {  
  5.             super.run();  
  6.             for (int i = 1; i <= 10; i++)    //打印10个数字  
  7.                 System.out.println(i);  
  8.         }  
  9.     }  
  10.     public static void main(String[] args) throws InterruptedException {  
  11.         MyThread thread = new MyThread();  
  12.         thread.start();                     //启动线程  
  13.         thread.interrupt();                 //启动线程后马上 中断线程  
  14.           
  15.         System.out.println(”第一次 : thread.interrupted() = ” + thread.isInterrupted());  
  16.         System.out.println(”第二次 : thread.interrupted() = ” + thread.isInterrupted());  
  17.     }  
  18. }  
public class IsInterruptedDemo {
    public static class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            for (int i = 1; i <= 10; i++)    //打印10个数字
                System.out.println(i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();
        thread.start();                     //启动线程
        thread.interrupt();                 //启动线程后马上 中断线程

        System.out.println("第一次 : thread.interrupted() = " + thread.isInterrupted());
        System.out.println("第二次 : thread.interrupted() = " + thread.isInterrupted());
    }
}


2. 返回值

  1. 第一次 : thread.interrupted() = true  
  2. 1  
  3. 2  
  4. 第二次 : thread.interrupted() = true  
  5. 3  
  6. 4  
  7. 5  
  8. 6  
  9. 7  
  10. 8  
  11. 9  
  12. 10  
第一次 : thread.interrupted() = true
1
2
第二次 : thread.interrupted() = true
3
4
5
6
7
8
9
10


3. 总结分析 : isInterrupted() 方法 只 判断 被调用对象的 该对象线程的 线程的中断 状态, 不管线程的真实运行状况, 即使当前线程正在运行, 但是线程调用了 interrupt() 方法, 其中断状态为 true, 因此 isInterrupted() 方法的返回值一直是 true;

4. 对比 interrupted() 方法 : interrupted() 方法反应的是真实的线程运行状态, 线程正在运行, 那么返回 false, 如果线程没有运行, 返回 true;

5. 对比 Interrupted() 方法 (静态与普通方法) : isInterrupted 方法是非静态方法, 哪个对象调用返回的就是哪个对象的中断状态; interrupted 是静态方法, 在哪个线程调用就是返回哪个线程的中断状态;




2. 异常法停止线程



(1) 线程循环中正常退出停止



退出方法 : 正常退出线程;

1. 前提 : 线程中执行一个循环;

2. 中断线程 : 执行线程中断操作, 调用 线程的 interrupt() 方法;

3. 查询中断标志 : 在线程中通过调用 interrupted 方法, 查询当前的线程中断标志, 之后该方法就会将中断标志清除;

4. 退出循环 : 如果查询到中断标志后, 直接使用 break 退出循环;

5. 弊端 : 在线程中, 线程没有真正的停止, 线程还是完整的执行了;


线程正常退出代码示例

1. 代码

  1. public class ExceptionInterruptDeo {  
  2.     public static class MyThread extends Thread{  
  3.         @Override  
  4.         public void run() {  
  5.             super.run();  
  6.             for(int i = 0; i < 500; i ++){  
  7.                 if(interrupted()){              //判断线程的中断状态, 如果中断直接 break  
  8.                     System.out.println(”停止状态, 退出”);  
  9.                     break;  
  10.                 }  
  11.                 System.out.println(i);  
  12.             }  
  13.             System.out.println(”MyThread 线程执行完毕”);//线程结束标志  
  14.         }  
  15.     }  
  16.     public static void main(String[] args) throws InterruptedException {  
  17.         MyThread thread = new MyThread();       //创建线程并执行  
  18.         thread.start();                         //启动线程  
  19.         Thread.sleep(1);                        //沉睡 1 毫秒  
  20.         thread.interrupt();                     //中断线程  
  21.         System.out.println(”主线程执行完毕”);  //判断主线程停止  
  22.     }  
  23. }  
public class ExceptionInterruptDeo {
    public static class MyThread extends Thread{
        @Override
        public void run() {
            super.run();
            for(int i = 0; i < 500; i ++){
                if(interrupted()){              //判断线程的中断状态, 如果中断直接 break
                    System.out.println("停止状态, 退出");
                    break;
                }
                System.out.println(i);
            }
            System.out.println("MyThread 线程执行完毕");//线程结束标志
        }
    }
    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();       //创建线程并执行
        thread.start();                         //启动线程
        Thread.sleep(1);                        //沉睡 1 毫秒
        thread.interrupt();                     //中断线程
        System.out.println("主线程执行完毕");  //判断主线程停止
    }
}


2. 执行结果

  1. … …  
  2. 50  
  3. 51  
  4. 52  
  5. 53  
  6. 54  
  7. 主线程执行完毕  
  8. 停止状态, 退出  
  9. MyThread 线程执行完毕  
... ...
50
51
52
53
54
主线程执行完毕
停止状态, 退出
MyThread 线程执行完毕


3. 总结分析 : 在线程中调用 interrupted() 方法, 查询中断标志(查询后立即清除中断标志), 弊端是停止线程后, 线程还是继续执行后面的逻辑, 继续执行完毕, 自动退出的;



(2) 异常退出线程



异常法退出线程 : 通过抛出一个异常, 来终止线程执行;

– 1. 前提 : 线程中执行一个循环;

– 2. 中断线程 : 执行线程中断操作, 调用 线程的 interrupt() 方法;

– 3. 查询中断标志 : 在线程中通过调用 interrupted 方法, 查询当前的线程中断标志, 之后该方法就会将中断标志清除;

– 4. 抛出异常退出循环 : 如果查询到中断标志后, 直接抛出一个 InterruptException 异常;

5. 捕获处理异常 : 要将整个 run 方法中的内容使用 try catch 代码块捕获, 因因为异常捕获后还会继续处理 try catch 之后的代码逻辑, 如果 try catch 代码块之后还有代码逻辑, 程序还会执行这段代码;

6. 好处 : 可以自由控制要中断哪些逻辑;


异常捕获规则

1. 执行逻辑 : 捕获异常后, 进行异常处理, 然后会继续执行 try catch 代码块 后面的代码逻辑;

2. 异常退出范围可控 : 可以自由控制中断哪些操作, 继续执行哪些操作;


代码测试

1. 代码

  1. public class ExceptionInterruptDeo {  
  2.     public static class MyThread extends Thread {  
  3.         @Override  
  4.         public void run() {  
  5.             try {  
  6.                 super.run();  
  7.                 for (int i = 0; i < 500; i++) {  
  8.                     if (interrupted()) { // 判断线程的中断状态, 如果中断直接 break  
  9.                         System.out.println(”停止状态, 抛出异常退出”);  
  10.                         throw new InterruptedException();  
  11.                     }// 中断标志 判定结束  
  12.                     System.out.println(i);  
  13.                 }//for 循环结束  
  14.                 System.out.println(”MyThread 线程执行完毕”);// 线程结束标志  
  15.             } catch (InterruptedException e) {  
  16.                 System.out.println(”线程中捕获异常代码块”);  
  17.                 e.printStackTrace();  
  18.             } // try catch 代码块  
  19.         }//run方法结束  
  20.     }//线程结束  
  21.   
  22.     public static void main(String[] args) throws InterruptedException {  
  23.         MyThread thread = new MyThread(); // 创建线程并执行  
  24.         thread.start(); // 启动线程  
  25.         Thread.sleep(1); // 沉睡 1 毫秒  
  26.         thread.interrupt(); // 中断线程  
  27.         System.out.println(”主线程执行完毕”); // 判断主线程停止  
  28.     }  
  29. }  
public class ExceptionInterruptDeo {
    public static class MyThread extends Thread {
        @Override
        public void run() {
            try {
                super.run();
                for (int i = 0; i < 500; i++) {
                    if (interrupted()) { // 判断线程的中断状态, 如果中断直接 break
                        System.out.println("停止状态, 抛出异常退出");
                        throw new InterruptedException();
                    }// 中断标志 判定结束
                    System.out.println(i);
                }//for 循环结束
                System.out.println("MyThread 线程执行完毕");// 线程结束标志
            } catch (InterruptedException e) {
                System.out.println("线程中捕获异常代码块");
                e.printStackTrace();
            } // try catch 代码块
        }//run方法结束
    }//线程结束

    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread(); // 创建线程并执行
        thread.start(); // 启动线程
        Thread.sleep(1); // 沉睡 1 毫秒
        thread.interrupt(); // 中断线程
        System.out.println("主线程执行完毕"); // 判断主线程停止
    }
}


2. 执行结果

  1. 113  
  2. 114  
  3. 115  
  4. 116  
  5. 主线程执行完毕  
  6. 停止状态, 抛出异常退出  
  7. 线程中捕获异常代码块  
  8. java.lang.InterruptedException  
  9.     at base.ExceptionInterruptDeo$MyThread.run(ExceptionInterruptDeo.java:12)  
113
114
115
116
主线程执行完毕
停止状态, 抛出异常退出
线程中捕获异常代码块
java.lang.InterruptedException
    at base.ExceptionInterruptDeo$MyThread.run(ExceptionInterruptDeo.java:12)


3. 总结分析 : 在 run 方法中将整个代码逻辑使用 try catch 代码块包裹, 异常法只能中断 try catch 代码块中的逻辑;




3. sleep() 中停止线程



(1) 先沉睡在终止线程



先 sleep() 再 interrupt() : 先沉睡, 再终止线程, 线程直接就停止了;


代码示例

1. 代码

  1. public class SleepInterruptDemo {  
  2.     public static class MyThread extends Thread{  
  3.         @Override  
  4.         public void run() {  
  5.             try {  
  6.                 System.out.println(”线程逻辑开始”);  
  7.                 super.run();  
  8.                 sleep(1000);    //启动后立即进入沉睡状态, 沉睡 1000ms  
  9.                 System.out.println(”线程逻辑结束”);  
  10.             } catch (InterruptedException e) {  
  11.                 System.out.println(”捕获到了异常 , 进入了 catch 代码块”);  
  12.                 e.printStackTrace();  
  13.             }//catch代码块  
  14.             System.out.println(”run 方法结束”);  
  15.         }//run方法  
  16.     }//线程  
  17.       
  18.     public static void main(String[] args) throws InterruptedException {  
  19.         MyThread thread = new MyThread();   //新建线程  
  20.         thread.start();                     //线程启动  
  21.         Thread.sleep(100);                  //沉睡 100 毫秒, 线程中  
  22.         thread.interrupt();                 //中断线程  
  23.     }  
  24. }  
public class SleepInterruptDemo {
    public static class MyThread extends Thread{
        @Override
        public void run() {
            try {
                System.out.println("线程逻辑开始");
                super.run();
                sleep(1000);    //启动后立即进入沉睡状态, 沉睡 1000ms
                System.out.println("线程逻辑结束");
            } catch (InterruptedException e) {
                System.out.println("捕获到了异常 , 进入了 catch 代码块");
                e.printStackTrace();
            }//catch代码块
            System.out.println("run 方法结束");
        }//run方法
    }//线程

    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();   //新建线程
        thread.start();                     //线程启动
        Thread.sleep(100);                  //沉睡 100 毫秒, 线程中
        thread.interrupt();                 //中断线程
    }
}


2. 执行结果

  1. 线程逻辑开始  
  2. 捕获到了异常 , 进入了 catch 代码块  
  3. run 方法结束  
  4. java.lang.InterruptedException: sleep interrupted  
  5.     at java.lang.Thread.sleep(Native Method)  
  6.     at base.SleepInterruptDemo$MyThread.run(SleepInterruptDemo.java:11)  
线程逻辑开始
捕获到了异常 , 进入了 catch 代码块
run 方法结束
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at base.SleepInterruptDemo$MyThread.run(SleepInterruptDemo.java:11)


3. 总结分析 : 在沉睡状态下, 如果调用 interrupt() 方法, 线程中会直接抛出 InterruptException 异常;



(2) 先终止线程 再 沉睡



先 终止线程 再 sleep : 先 终止线程, 在 sleep, 那么 sleep 之前的代码需要实现相关逻辑


代码示例

1. 代码 : 与上面的区别是 在 sleep 之前有一段 循环逻辑;

  1. public class SleepInterruptDemo {  
  2.     public static class MyThread extends Thread{  
  3.         @Override  
  4.         public void run() {  
  5.             try {  
  6.                 System.out.println(”线程逻辑开始”);  
  7.                 super.run();  
  8.                 for(int i = 0; i < 500; i ++)  
  9.                     System.out.println(i);  
  10.                 sleep(1000);    //启动后立即进入沉睡状态, 沉睡 1000ms  
  11.                 System.out.println(”线程逻辑结束”);  
  12.             } catch (InterruptedException e) {  
  13.                 System.out.println(”捕获到了异常 , 进入了 catch 代码块”);  
  14.                 e.printStackTrace();  
  15.             }//catch代码块  
  16.             System.out.println(”run 方法结束”);  
  17.         }//run方法  
  18.     }//线程  
  19.       
  20.     public static void main(String[] args) throws InterruptedException {  
  21.         MyThread thread = new MyThread();   //新建线程  
  22.         thread.start();                     //线程启动  
  23.         thread.interrupt();                 //中断线程  
  24.         System.out.println(”主线程中断线程”);  
  25.     }  
  26. }  
public class SleepInterruptDemo {
    public static class MyThread extends Thread{
        @Override
        public void run() {
            try {
                System.out.println("线程逻辑开始");
                super.run();
                for(int i = 0; i < 500; i ++)
                    System.out.println(i);
                sleep(1000);    //启动后立即进入沉睡状态, 沉睡 1000ms
                System.out.println("线程逻辑结束");
            } catch (InterruptedException e) {
                System.out.println("捕获到了异常 , 进入了 catch 代码块");
                e.printStackTrace();
            }//catch代码块
            System.out.println("run 方法结束");
        }//run方法
    }//线程

    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();   //新建线程
        thread.start();                     //线程启动
        thread.interrupt();                 //中断线程
        System.out.println("主线程中断线程");
    }
}


2. 执行结果

  1. 496  
  2. 497  
  3. 498  
  4. 499  
  5. 捕获到了异常 , 进入了 catch 代码块  
  6. run 方法结束  
  7. java.lang.InterruptedException: sleep interrupted  
  8.     at java.lang.Thread.sleep(Native Method)  
  9.     at base.SleepInterruptDemo$MyThread.run(SleepInterruptDemo.java:12)  
496
497
498
499
捕获到了异常 , 进入了 catch 代码块
run 方法结束
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at base.SleepInterruptDemo$MyThread.run(SleepInterruptDemo.java:12)


3. 总结 : 使用 Interrupt 方法后, 如果正在执行循环, 就不会抛异常退出线程, 进入 sleep 状态后, 会立即抛出异常, 退出线程;





4. stop() 停止线程



(1) stop 方法停止线程的效果



stop 停止线程

1. 立即停止 : 调用 stop() 方法停止线程, 比较暴力, 会立即停止当前的线程;

2. 抛出异常 : 使用 stop() 方法停止线程会抛出一个 ThreadDeath 异常, 这个异常可以不捕捉;

3. 适用场景 : 适用该方法停止线程, 前提示 线程的相关数据 和 线程本身 都不再使用了, 否则会造成数据混乱;


stop() 停止线程效果演示

1. 代码示例

  1. public class StopDemo {  
  2.     public static class MyThread extends Thread{  
  3.         @Override  
  4.         public void run() {  
  5.             try {  
  6.                 System.out.println(”线程逻辑开始”);  
  7.                 super.run();  
  8.                 for(int i = 0; i < 5000; i ++){  
  9.                     System.out.println(i);  
  10.                     sleep(100);   
  11.                 }  
  12.                 System.out.println(”线程逻辑结束”);  
  13.             } catch (InterruptedException e) {  
  14.                 System.out.println(”捕获到了 InterruptedException 异常 , 进入了 catch 代码块”);  
  15.                 e.printStackTrace();  
  16.             }//catch代码块  
  17.             System.out.println(”run 方法结束”);  
  18.         }//run方法  
  19.     }//线程  
  20.       
  21.     public static void main(String[] args) throws InterruptedException {  
  22.         MyThread thread = new MyThread();   //新建线程  
  23.         thread.start();                     //线程启动  
  24.         Thread.sleep(500);                  //沉睡 500ms, 让线程打印 5 个数字  
  25.         thread.stop();                      //中断线程  
  26.         System.out.println(”主线程中断线程”);  
  27.     }  
  28. }  
public class StopDemo {
    public static class MyThread extends Thread{
        @Override
        public void run() {
            try {
                System.out.println("线程逻辑开始");
                super.run();
                for(int i = 0; i < 5000; i ++){
                    System.out.println(i);
                    sleep(100); 
                }
                System.out.println("线程逻辑结束");
            } catch (InterruptedException e) {
                System.out.println("捕获到了 InterruptedException 异常 , 进入了 catch 代码块");
                e.printStackTrace();
            }//catch代码块
            System.out.println("run 方法结束");
        }//run方法
    }//线程

    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();   //新建线程
        thread.start();                     //线程启动
        Thread.sleep(500);                  //沉睡 500ms, 让线程打印 5 个数字
        thread.stop();                      //中断线程
        System.out.println("主线程中断线程");
    }
}


2. 运行结果

  1. 线程逻辑开始  
  2. 0  
  3. 1  
  4. 2  
  5. 3  
  6. 4  
  7. 主线程中断线程  
线程逻辑开始
0
1
2
3
4
主线程中断线程


3. 总结分析 : 线程直接中断了, 线程中 run() 方法的最后一行代码也没有执行, 循环逻辑结束也没有执行, 说明线程很暴力的直接退出, 没有任何处理;




(2) stop 方法停止线程 捕获 ThreadDeath 异常




关于异常捕捉

1. 捕捉 ThreadDeath 异常 : 线程捕获异常处理后, 还会继续执行 try catch 代码块下面的代码;

2. 不捕捉 ThreadDeath 异常 : 线程直接从 stop 时刻退出, 不会执行下面的代码;


stop() 停止线程 并 捕获异常 效果演示

1. 代码示例 : 代码中比上面多了一个 catch ThreadDeath 异常的代码块, 其它一样;

  1. public class StopDemo {  
  2.     public static class MyThread extends Thread{  
  3.         @Override  
  4.         public void run() {  
  5.             try {  
  6.                 System.out.println(”线程逻辑开始”);  
  7.                 super.run();  
  8.                 for(int i = 0; i < 5000; i ++){  
  9.                     System.out.println(i);  
  10.                     sleep(100);   
  11.                 }  
  12.                 System.out.println(”线程逻辑结束”);  
  13.             } catch (InterruptedException e) {  
  14.                 System.out.println(”捕获到了 InterruptedException 异常 , 进入了 catch 代码块”);  
  15.                 e.printStackTrace();  
  16.             }catch (ThreadDeath e){  
  17.                 System.out.println(”捕获到了 ThreadDeath 异常 , 进入了 catch 代码块”);  
  18.                 e.printStackTrace();  
  19.             }//catch代码块  
  20.             System.out.println(”run 方法结束”);  
  21.         }//run方法  
  22.     }//线程  
  23.       
  24.     public static void main(String[] args) throws InterruptedException {  
  25.         MyThread thread = new MyThread();   //新建线程  
  26.         thread.start();                     //线程启动  
  27.         Thread.sleep(500);                  //沉睡 500ms, 让线程打印 5 个数字  
  28.         thread.stop();                      //中断线程  
  29.         System.out.println(”主线程中断线程”);  
  30.     }  
  31. }  
public class StopDemo {
    public static class MyThread extends Thread{
        @Override
        public void run() {
            try {
                System.out.println("线程逻辑开始");
                super.run();
                for(int i = 0; i < 5000; i ++){
                    System.out.println(i);
                    sleep(100); 
                }
                System.out.println("线程逻辑结束");
            } catch (InterruptedException e) {
                System.out.println("捕获到了 InterruptedException 异常 , 进入了 catch 代码块");
                e.printStackTrace();
            }catch (ThreadDeath e){
                System.out.println("捕获到了 ThreadDeath 异常 , 进入了 catch 代码块");
                e.printStackTrace();
            }//catch代码块
            System.out.println("run 方法结束");
        }//run方法
    }//线程

    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();   //新建线程
        thread.start();                     //线程启动
        Thread.sleep(500);                  //沉睡 500ms, 让线程打印 5 个数字
        thread.stop();                      //中断线程
        System.out.println("主线程中断线程");
    }
}


2. 运行结果

  1. 线程逻辑开始  
  2. 0  
  3. 1  
  4. 2  
  5. 3  
  6. 4  
  7. 主线程中断线程  
  8. 捕获到了 ThreadDeath 异常 , 进入了 catch 代码块  
  9. run 方法结束  
  10. java.lang.ThreadDeath  
  11.     at java.lang.Thread.stop(Unknown Source)  
  12.     at com.hanshuliang.thread.StopDemo.main(StopDemo.java:31)  
线程逻辑开始
0
1
2
3
4
主线程中断线程
捕获到了 ThreadDeath 异常 , 进入了 catch 代码块
run 方法结束
java.lang.ThreadDeath
    at java.lang.Thread.stop(Unknown Source)
    at com.hanshuliang.thread.StopDemo.main(StopDemo.java:31)


3. 总结分析 : 如果捕获了 ThreadDeath 异常, 就会处理这个异常, 并会执行异常处理后面的代码, run() 方法的最后一行代码也执行完毕了;




5. return 停止线程



return 停止线程说明

1. 执行过程 : 线程运行中, 随时监测中断标记, 如果检测到中断标记后, 直接 return 退出 run 方法;

– 2. 不建议使用该方法, 多个 return 会污染代码;


return 退出演示

1. 代码示例

  1. public class ReturnDemo {  
  2.     public static class MyThread extends Thread{  
  3.         @Override  
  4.         public void run() {  
  5.             super.run();  
  6.             for(int i = 0; i < 500; i ++){  
  7.                 if(interrupted()){              //判断线程的中断状态, 如果中断直接 break  
  8.                     System.out.println(”停止状态, return 退出”);  
  9.                     return;  
  10.                 }  
  11.                 System.out.println(i);  
  12.             }  
  13.             System.out.println(”MyThread 线程执行完毕”);//线程结束标志  
  14.         }  
  15.     }  
  16.     public static void main(String[] args) throws InterruptedException {  
  17.         MyThread thread = new MyThread();       //创建线程并执行  
  18.         thread.start();                         //启动线程  
  19.         Thread.sleep(1);                        //沉睡 1 毫秒  
  20.         thread.interrupt();                     //中断线程  
  21.         System.out.println(”主线程执行完毕”);  //判断主线程停止  
  22.     }  
  23. }  
public class ReturnDemo {
    public static class MyThread extends Thread{
        @Override
        public void run() {
            super.run();
            for(int i = 0; i < 500; i ++){
                if(interrupted()){              //判断线程的中断状态, 如果中断直接 break
                    System.out.println("停止状态, return 退出");
                    return;
                }
                System.out.println(i);
            }
            System.out.println("MyThread 线程执行完毕");//线程结束标志
        }
    }
    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();       //创建线程并执行
        thread.start();                         //启动线程
        Thread.sleep(1);                        //沉睡 1 毫秒
        thread.interrupt();                     //中断线程
        System.out.println("主线程执行完毕");  //判断主线程停止
    }
}


2. 执行结果

  1. … …  
  2. 35  
  3. 36  
  4. 37  
  5. 38  
  6. 39  
  7. 主线程执行完毕  
  8. 停止状态, return 退出  
... ...
35
36
37
38
39
主线程执行完毕
停止状态, return 退出


3. 总结分析 : 使用 return 直接退出 run 方法, 确实实现了立即停止线程的目的, 但是我们还是建议使用 异常法 控制线程停止;



.



转载注明出处 : http://blog.youkuaiyun.com/shulianghan/article/details/52369486

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值