线程的启动和中断方式
  1. X extends Thread;,然后 X.start
  2. X implements Runnable;然后交给 Thread 运行

两种方式都是把业务逻辑写在run()方法里,调用start()方法启动。

创建线程的时候,通过new Thread() 其实只是new了一个Thread的实例,还没有跟操作系统的线程挂起钩来。只有执行了start()方法,才算是启动了真正意义上的线程。

java 线程主动退出 java线程中止_java

中止
线程自然终止

要么是 run 执行完成了,要么是抛出了一个未处理的异常导致线程提前结束

stop

java 线程主动退出 java线程中止_i++_02


这些api已经不建议使用了,原因是因为方法太野蛮,完全不给线程释放资源的机会

中断

安全的中止则是其他线程通过调用某个线程(比如A线程)的interrupt()方法。告诉线程A,请求中断。但是不代表A会立刻停止。同样的 A 线程完全可以不理会这种中断请求。线程可以通过检查自身的中断标志位是否被置为 true 来进行响应。

线程通过方法 isInterrupted()来进行判断是否被请求中断。中断后请求标致位为true

public class InterruptedDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread aThread = new AThread();
        aThread.start();
        Thread.sleep(200);
        aThread.interrupt();
    }
}

class AThread extends Thread {
    int i = 0;

    @Override
    public void run() {
        while (!isInterrupted()) {
            i++;
            System.out.println(i);
            System.out.println(interrupted());
        }
        System.out.println(isInterrupted());
    }
}

java 线程主动退出 java线程中止_java_03


也可以调用静态方法Thread.interrupted()来进行判断当前线程是否被中断,不过 Thread.interrupted()

会同时将中断标识位改写为 false。

public class InterruptedDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread aThread = new AThread();
        aThread.start();
        Thread.sleep(200);
        aThread.interrupt();
    }
}

class AThread extends Thread {
    int i = 0;

    @Override
    public void run() {
        while (!Thread.interrupted()) {
            i++;
            System.out.println(i);
            System.out.println(Thread.interrupted());
        }
        System.out.println(isInterrupted());
    }
}

java 线程主动退出 java线程中止_System_04


如果一个线程处于了阻塞状态(如线程调用了 thread.sleep、thread.join、

thread.wait 等),则在线程在检查中断标示时如果发现中断标示为 true,则会在

这些阻塞方法调用处抛出 InterruptedException 异常,并且在抛出异常后会立即

将线程的中断标示位清除,即重新设置为 false。

public class InterruptedDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread aThread = new AThread();
        aThread.start();
        Thread.sleep(200);
        aThread.interrupt();
    }
}

class AThread extends Thread {
    int i = 0;

    @Override
    public void run() {
        while (!isInterrupted()) {
            i++;
            System.out.println(i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("抛出异常 ------ "+ isInterrupted());
                interrupt();
                e.printStackTrace();
            }
        }
        System.out.println(isInterrupted());
    }
}

java 线程主动退出 java线程中止_i++_05


不建议自定义一个取消标志位来中止线程的运行。因为 run()方法里有阻塞调

用时会无法很快检测到取消标志,线程必须从阻塞调用返回后,才会检查这个取

消标志。

还有要注意的是 处于 死锁状态 的 线程无法被中断