线程停止的三种方式
1. 设置标志位(无法处理线程阻塞时的问题);
2. 调用Thread类提供的stop
方法强行关闭线程;
3. 通过Thread类提供的interrupt
方法
举例:设置标志位
class InterruptThread extends Thread{
private boolean flag = true;
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
int i =0;
while(flag){
i++;
System.out.println(Thread.currentThread().getName()+",i= "+i);
}
}
}
public class TestInterrupt {
public static void main(String[] args) throws InterruptedException {
InterruptThread t1 = new InterruptThread();
t1.start();
//子线程和主线程并发执行,为了看到效果,休眠1s
Thread.sleep(1000);
t1.setFlag(false);
}
}
举例:使用stop
class InterruptThread extends Thread{
private boolean flag = true;
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
int i =0;
while(flag){
i++;
System.out.println(Thread.currentThread().getName()+",i= "+i);
}
}
}
public class TestInterrupt {
public static void main(String[] args) throws InterruptedException {
InterruptThread t1 = new InterruptThread();
t1.start();
//子线程和主线程并发执行,为了看到效果,休眠1s
Thread.sleep(1000);
t1.stop();
}
}
使用stop方法不推荐使用:(1)该方法已经过期;(2)会产生不完整的数据。
举例:使用中断(非阻塞情况下)
class InterruptThread extends Thread{
private boolean flag = true;
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
int i =0;
while(flag){
//查看当前中断状态
boolean bool = Thread.currentThread().isInterrupted();
System.out.println(bool);
i++;
System.out.println(Thread.currentThread().getName()+",i= "+i);
}
}
}
public class TestInterrupt {
public static void main(String[] args) throws InterruptedException {
InterruptThread t1 = new InterruptThread();
t1.start();
//子线程和主线程并发执行,为了看到效果,休眠1s
Thread.sleep(1000);
t1.interrupt();
}
}
结果表示:interrupt并不能中断线程,只是将原来的中断标志由false
改为true
。这是在非阻塞的情况下。
举例:使用中断(阻塞情况下)
class InterruptThread extends Thread {
private boolean flag = true;
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
int i = 0;
while (flag) {
try {
Thread.sleep(200);
boolean bool = Thread.currentThread().isInterrupted();
System.out.println("当前线程状态为:" + bool);
System.out.println(Thread.currentThread().getName()
+ ",i = " + i++);
} catch (InterruptedException e) {
System.out.println("抛出中断异常");
boolean bool = Thread.currentThread().isInterrupted();
System.out.println(bool); //false
return;
}
}
System.out.println("线程停止");
}
}
public class TestInterrupt {
public static void main(String[] args) throws InterruptedException {
InterruptThread t1 = new InterruptThread();
t1.start();
//子线程和主线程并发执行,为了看到效果,休眠1s
Thread.sleep(1000);
t1.interrupt();
}
}
结果表示:在阻塞情况下(sleep),直接会抛出中断异常
,并且把将中断标志true
又改回为false
。
总结第三种:
1)若线程中为非阻塞(没有使用类似sleep/wait/join)时,调用线程对象的interrupt方法不会真正中断线程,只是简单的将线程的状态由false---->true(中断状态),我们可以根据此状态来进一步确定如何处理线程。
2)若线程中调用了阻塞线程的方法,如:sleep/wait/join,此时在调用线程的interrupt方法时,会抛出InterruptedException。同时将线程状态又还原为false。