1.如何终止一个线程
终止线程有三种方法
有三种方法可以使终止线程。
1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的 结果)。 不推荐
3. 使用interrupt方法中断线程。推荐
第一种方法终止线程(使用退出标志,看注释就好,注释写的很清楚了)
public class TestThread extends Thread{
//锁住exit,保证当前只有一个线程能够访问并修改exit变量
//通过设置这个标志来控制while循环是否退出
public volatile boolean exit = false;
public void run(){
while(!exit);
System.out.println("跳出循环了!");
}
public static void main(String[] args) throws Exception{
TestThread thread = new TestThread();
thread.start();
sleep(5000);//使当前线程延迟5秒后启动(主线程)
thread.exit = true;//更改exit跳出while循环
thread.join();//让调用该方法的thread完成run方法里面的内容后,在执行join()方法后面的东西
System.out.println("线程退出!");
}
}
第二种方法终止线程使用stop方法可以强行终止正在运行或挂起的线程。我们可以使用如下的代码来终止线程
thread.stop();
虽然使用上面的代码可以终止线程,但使用stop方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果,因此,并不推荐使用stop方法来终止线程。(虽然笔者目前还没有深入研究为什么可能会产生不可预料的结果,但是这里希望大家有这个意识,不要使用这种方式强行终止一个线程,当然,具体原因有兴趣的朋友可以再仔细阅读JDK相关文档)
第三种方法终止线程
使用interrupt方法终止线程
(1)线程处于阻塞状态,如使用了sleep方法。
(2)使用while(!isInterrupted()){……}来判断线程是否被中断。
第一种情况(看注释,注释写得很清楚了):
public class ThreadInterrupt extends Thread{
@Override
public void run() {
try {
sleep(50000);//该线程延迟50秒后执行
} catch (InterruptedException e) {
System.out.println(this.isInterrupted() + " " + e.getMessage());
}
}
public static void main(String[] args) throws Exception{
Thread thread = new ThreadInterrupt();
thread.start();
System.out.println(thread.isInterrupted());
System.in.read();//随意输入一些内容
thread.interrupt();//调用interrupt方法,使得sleep方法抛出一个interruptedException例外
System.out.println(thread.isInterrupted());//在异常尚未捕捉到时,看一下这个interrupted这个变量的值
thread.join();//使调用这个join的thread执行完run方法后,再执行后面的内容
System.out.println("线程已经退出");
}
}
我们看到,当线程调用interrupt方法后,检测到的isInterrupted()方法的值为true,但是捕获到这个异常后isInterrupted()已经被重新置为false了,即线程的状态变为非中断状态,那么如果你的run中是一个循环的话,那么如果catch语句没有处理异常,则下一 次循环中isInterrupted()为false,线程会继续执行,可能你N次抛出异常,也无法让线程停止,如下面的例子:
我们看到这里,只是捕获了异常,而没有做相应的处理,导致线程仍旧再执行,如下:
我们看到这里,只是捕获了异常,而没有做相应的处理,导致线程仍旧再执行,如下:
因此,我们可以使用一种叫做“二次惰性检测(double check)”的方式,能在提高效率的基础上又确保线程真正中同步控制中,即不以isInterrupted ()为循环条件。而以一个标记作为循环条件,如下:
public class ThreadB extends Thread{
private boolean isInterrupted=false;
int count=0;
public void interrupt(){
isInterrupted = true;
super.interrupt();
}
public void run(){
System.out.println(getName()+"将要运行...");
while(!isInterrupted){
System.out.println(getName()+"运行中"+count++);
try{
Thread.sleep(400);
}catch(InterruptedException e){
System.out.println(getName()+"从阻塞中退出...");
System.out.println("this.isInterrupted()="+this.isInterrupted());
}
}
System.out.println(getName()+"已经终止!");
}
public static void main(String[] args) throws Exception{
ThreadB tb=new ThreadB();
tb.setName("Thread b");
tb.start();
sleep(2000);
System.out.println(tb.getName()+"正在被中断...");
tb.interrupt();
System.out.println("tb.isInterrupted()="+tb.isInterrupted());
}
}
输出如下:
在这第二篇有关JAVA线程的内容,我就先说这么多,也希望,无论是我写的有问题还是对这里的内容有疑惑,都希望大家提出来!