1.stop()方法
该方法已过时。 该方法具有固有的不安全性。用 Thread.stop 来终止线程将释放它已经锁定的所有监视器。
2.如何停止线程
既然Thread.stop方法已经过时,那么如何停止线程呢?
只有一种,那就是使run()方法结束。
使用多线程时,开启多线程运行,运行代码通常都是循环结构。只要控制循环,就可以让run()方法结束,即线程结束。
public class StopThreadDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
StopThread st = new StopThread();
//开启两个线程
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
//启动线程
t1.start();
t2.start();
//定义变量
int num = 0;
while(true) {
//当num等于60时,停止所有线程
if(num == 60) {
//调用st的changeFlag()方法,将标记改为假,循环结束,线程也就停止
st.changeFlag();
//结束本循环
break;
}
System.out.println(Thread.currentThread().getName() + (num++) + " is running~~~");
}
}
}
class StopThread implements Runnable {
//定义判断标记,默认值为真
private boolean flag = true;
//重写run方法
public void run() {
while(flag) {
System.out.println(Thread.currentThread().getName() + " is running...");
}
}
//改变标记方法
public void changeFlag() {
flag = false;
}
}
运行程序
当线程中run()方法的循环标记为假是,循环结束,run()方法结束,线程也就停止。
3.interrupt()方法
有一种情况,程序不会停下来:当run()方法是同步方法,并且执行代码中含有wait()并且外界不干预时。
把线程类改为如下
class InterruptThread implements Runnable {
//定义判断标记,默认值为真
private boolean flag = true;
//重写run方法
public synchronized void run() {
while(flag) {
try{
wait();
}catch(InterruptedException e){
System.out.println(Thread.currentThread().getName() + " has a exception...");
changeFlag();
}
System.out.println(Thread.currentThread().getName() + " is running...");
}
}
//改变标记方法
public void changeFlag() {
flag = false;
}
}
运行线程类
public class InterruptThreadDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
InterruptThread st = new InterruptThread();
//开启两个线程
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
//启动线程
t1.start();
t2.start();
//定义变量
int num = 0;
while(true) {
//当num等于60时,停止所有线程
if(num == 60) {
//结束本循环
break;
}
System.out.println(Thread.currentThread().getName() + "-" + (num++) + " is running~~~");
}
}
}
运行程序
我们看到程序在没有外界干预下,停止不动。
这是因为两个线程在执行时都运行wait方法而放弃执行资格进入冻结状态,并且没有线程对其notify,程序读不到changeFlag()方法,无法结束循环,所以两个线程一直保持冻结状态,程序停止不动。
那么,如何在主线程中对冻结的线程进行干预而使程序正常执行呢?--------使用interrupt()方法中断线程。
如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。
将InterruptThreadDemo类改为如下
public class InterruptThreadDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
InterruptThread st = new InterruptThread();
//开启两个线程
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
//启动线程
t1.start();
t2.start();
//定义变量
int num = 0;
while(true) {
//当num等于60时,停止所有线程
if(num == 60) {
//中断线程冻结状态
t1.interrupt();
t2.interrupt();
//结束本循环
break;
}
System.out.println(Thread.currentThread().getName() + "-" + (num++) + " is running~~~");
}
}
}
运行结果
我们看到程序能够运行完并且自己结束。说明线程的冻结状态被终止,标记flag被改为false,循环结束。
程序运行后看到结果中包含两条语句:Thread-0 has a exception... Thread-1 has a exception...
说明调用interrupt()方法,会产生InterruptedException异常。
总结:线程调用了Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法时,线程进入冻结状态,此时调用Thread类的interrupt()方法,可以终止线程的冻结状态,并且会受到一个InterruptedException异常。
注意:
一定要注意stop()和interrupt()方法的区别!
stop()方法用于停止线程运行,已过时。
interrupt()方法停止线程冻结状态,使线程恢复到运行状态。