这些天在琢磨线程的问题,发现在java中要实现“杀死”线程的问题,是一个比较棘手的问题。在java的老版本中提供了stop()方法来实现杀死线程,但是stop方法是不安全的,它暴力的终端线程的执行,会使JVM的内存机制受到挑战,具体原因我也不是很理解,请参考以下Oracel的解释,链接如下:英文原址
其实在上面的链接中已经给出了一种替代stop()的方法,会在以下介绍到。我们杀死线程的中心思想只有一个那就是让线程自己走完它的流程。基于这种思想,我们有这么几种方式:
有一篇博客强烈推荐:interrupt理解
1. 设置全局变量标志
通过设置全局变量来控制线程,具体看代码
public static volatile boolean isRunning=true;
@Override
public void run() {
// TODO Auto-generated method stub
int i=0;
while (isRunning) {
long time=System.currentTimeMillis();
while(System.currentTimeMillis()-time<1000){
}
i++;
System.out.println("时间过去了"+i+"s"+Thread.currentThread().toString());
}
System.out.println("GlobalVeribelThrea end"+Thread.currentThread().toString());
super.run();
}
通过isRunning变量来控制循环体,Test代码如下:
public static void main(String[] args) {
GlobalVeribelThread globalVeribelThread=new GlobalVeribelThread();
globalVeribelThread.start();
GlobalVeribelThread globalVeribelThread2=new GlobalVeribelThread();
globalVeribelThread2.start();
try {
globalVeribelThread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
GlobalVeribelThread.isRunning=false;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
GlobalVeribelThread.isRunning=true;
}
这种方式,控制线程,如果发生多线程同步问题,就需要对全局变量加锁操作,同步的精髓在于可见性,以及原子性,volatile关键字只保证了可见性,关于volatile关键字,ibm有篇文章很好Java volatile关键字
2. 通过interrupt()脱离线程阻塞状态,跳出程序体。
使用interrupt()方法之前得先明确线程的基本知识,线程的基本状态等基础知识,interrupt方法是将进入到阻塞状态的线程抛出一个中断异常并改变线程的阻塞状态,通过这一点我们可以在捕获中断异常中执行跳出循环体操作。具体见代码:
@Override
public void run() {
int i=0;
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("thread1 interrupt exception" + e.toString());
break;
}
i++;
System.out.println("thread1 is :"+i+" thread name:"+Thread.currentThread().getName());
}
System.out.println("thread end"+Thread.currentThread().getName());
}
测试代码如下:
public static void main(String[] args) {
TestThread1 testThread1=new TestThread1();
testThread1.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
testThread1.interrupt();
}
结果是:
thread1 is :1 thread name:Thread-0
thread1 is :2 thread name:Thread-0
thread1 is :3 thread name:Thread-0
thread1 interrupt exceptionjava.lang.InterruptedException: sleep interrupted
thread endThread-0
达到了“杀死”线程的目的。