标签:interrupt inf string i++ 不能 inter 一个 安全 静态
线程的中断
因为线程中的stop()方法,已经被弃用,因为它是不安全的,使用它相当于你在家用电脑,直接在没有预知的情况下直接给你停电了一样,太暴力,所以不能用它。应该用 interrupt(),这个不是直接中断,而是将当前线程标志为中断标记,只是一个标记。怎么用,代码示例如下:
1 package com.huolongluo.coindemo.thread; 2 3 /** 4 * Created by 火龙裸 on 2019/11/13. 5 * desc : 线程的中断 6 * version: 1.0 7 */ 8 public class ThreadDemo { 9 public static void main(String[] args) { 10 MyThread myThread = new MyThread(); 11 myThread.start();//启动子线程 12 13 try { 14 Thread.sleep(500);//当前工作的那个线程(主线程)沉睡500毫秒(也就是让子线程跑500毫秒钟) 15 } catch (InterruptedException e) { 16 e.printStackTrace(); 17 } 18 // myThread.stop();//不安全,已被弃用 19 myThread.interrupt();//主线程沉睡500毫秒后,继续在主线程当中,通过“myThread”对象,将子线程标记为中断, 20 } 21 } 22 23 class MyThread extends Thread { 24 @Override 25 public void run() { 26 for (int i = 0; i < 1000000; i++) { 27 //(Thread.interrupted()返回当前线程(这个代码所运行的那个线程)标志位(当前代码所运行在的那个线程状态),并将标志位重置 28 if (Thread.interrupted()) {//也可以使用isInterrupted(),判断当前线程(这个代码所运行的那个线程)标志位,但isInterrupted()不会重置标志位 29 //收尾工作 30 return; 31 } 32 System.out.println("number: " + i); 33 } 34 } 35 }
注意:Thread.interrupted()是个静态方法,和直接使用isInterrupted()是有区别的。虽然都会返回当前代码执行的那个线程的线程状态,但是Thread.interrupted()还会同时将标志位重置为false。
另外一种情况,当子线程有沉睡/等待操作,主线程当中通过子线程对象调用了interrupt()方法,将子线程的线程标志为标记为中断,因为子线程有睡眠,所以会先抛出子线程的异常,而不是执行判断Thread.interrupted()判断,这个时候所以收尾工作应该在子线程中的e.printStackTrace();之后,子线程所抛出的InterruptedException异常,也会将自己的线程中断状态标志位重置为false,所以要是没有在子线程的e.printStackTrace()之后做收尾工作,相当于没有中断,仍旧会一直循环执行下去。因为这个时候子线程在休眠,为了避免浪费资源,收尾工作需要在子线程抛异常的那个位置。
代码示例如下:
1 package com.huolongluo.coindemo.thread; 2 3 /** 4 * Created by 火龙裸 on 2019/11/13. 5 * desc : 线程的中断 6 * version: 1.0 7 */ 8 public class ThreadDemo { 9 public static void main(String[] args) { 10 MyThread myThread = new MyThread(); 11 myThread.start();//启动子线程 12 13 try { 14 Thread.sleep(500);//当前工作的那个线程(主线程)沉睡500毫秒(也就是让子线程跑500毫秒钟) 15 } catch (InterruptedException e) { 16 e.printStackTrace(); 17 } 18 // myThread.stop();//不安全,已被弃用 19 myThread.interrupt();//主线程沉睡500毫秒后,继续在主线程当中,通过“myThread”对象,将子线程标记为中断, 20 } 21 } 22 23 class MyThread extends Thread { 24 @Override 25 public void run() { 26 for (int i = 0; i < 1000000; i++) { 27 //(Thread.interrupted()返回当前线程(这个代码所运行的那个线程)标志位(当前代码所运行在的那个线程状态),并将标志位重置 28 if (Thread.interrupted()) {//也可以使用isInterrupted(),判断当前线程(这个代码所运行的那个线程)标志位,但isInterrupted()不会重置标志位 29 System.out.println("判断标志位"); 30 //收尾工作 31 return; 32 } 33 try { 34 Thread.sleep(2000);//当前子线程沉睡2秒 35 } catch (InterruptedException e) {//InterruptedException异常,也会将标志位重置 36 e.printStackTrace(); 37 //收尾工作 38 System.out.println("子线程 收尾啦"); 39 return; 40 } 41 System.out.println("number: " + i); 42 } 43 } 44 }
运行结果:
还有一种,睡眠方式:SystemClock.sleep(2000),它与Sleep(2000)的区别是,SystemClock.sleep(2000)把InterruptedException异常给吃掉了,它不会抛异常,所以也不会重置标志位,只是单纯的让当前线程睡2秒钟。示例代码如下:
运行结果:
只打印一行,然后再return结束掉了。
标签:interrupt inf string i++ 不能 inter 一个 安全 静态
原文地址:https://www.cnblogs.com/huolongluo/p/11854124.html