线程的启动和中断方式
- X extends Thread;,然后 X.start
- X implements Runnable;然后交给 Thread 运行
两种方式都是把业务逻辑写在run()方法里,调用start()方法启动。
创建线程的时候,通过new Thread() 其实只是new了一个Thread的实例,还没有跟操作系统的线程挂起钩来。只有执行了start()方法,才算是启动了真正意义上的线程。

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

这些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());
}
}
也可以调用静态方法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());
}
}
如果一个线程处于了阻塞状态(如线程调用了 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());
}
}
不建议自定义一个取消标志位来中止线程的运行。因为 run()方法里有阻塞调
用时会无法很快检测到取消标志,线程必须从阻塞调用返回后,才会检查这个取
消标志。
还有要注意的是 处于 死锁状态 的 线程无法被中断
















