如何正确中断 一个线程?
1、通过线程提供的方法
- interrupt
通过调用此方法,系统就会给当前线程打上一个中断标记(true),默认为false,如果其他线程中调用当前线程中的此方法,表示告诉当前线程你可以停止了,当前线程也可以不理睬继续执行 - isInterrupted
判断当前线程是否被中断,根据当前线程中断标志位,做相关的处理 - Thread.interrupted()
判断线程是否被中断,此方法是个静态方法,跟isInterrupted 不同的是,在判断的之后会重置中断标记位为false
1.1 通过Thread 提供的方法来中断操作(建议使用)
final Thread thread=new Thread("TestCustomisInterrupted"){
@Override
public void run() {
super.run();
//默认标志位 为false
while (!isInterrupted()){
System.out.println(currentThread().getName()+"::::runing.......");
}
System.out.println("执行完成::::"+isInterrupted()); //true
}
};
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
上边是个比较简单的例子,如果当前线程执行体里边有阻塞方法会是什么样的情况:
final Thread thread=new Thread("TestCustomisInterrupted"){
@Override
public void run() {
super.run();
//默认标志位 为false
while (!isInterrupted()){
try {
sleep(1000);
System.out.println(currentThread().getName()+"::::runing.......");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("执行完成::::"+isInterrupted()); //true
}
};
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
输入结果
TestCustomisInterrupted::::runing.......
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.example.socket.MyClass$1.run(MyClass.java:78)
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
会抛出一个中断异常,并且把中断标志为重置为false,线程不会停止会一直执行,如果想让程序继续执行中断操作可以在,异常里边继续设置中断操作
利用Thread.interrupted() 静态方法判断,如果发生中断之后,会直接把中断标记位设置为fasle
final Thread thread=new Thread("TestCustomisInterrupted"){
@Override
public void run() {
super.run();
//默认标志位 为false
while (!Thread.interrupted()){
System.out.println(currentThread().getName()+"::::runing.......");
}
System.out.println("执行完成::::"+isInterrupted()); //true
}
};
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
执行完成::::false
2、通过线程自定义字段去终止线程
class MyRunable implements Runnable{
boolean isRun=true;
public boolean isRun() {
return isRun;
}
public void setRun(boolean run) {
isRun = run;
}
@Override
public void run() {
while (isRun){
System.out.println("::::runing.......");
}
System.out.println("执行完成::::"+isRun); //true
}
}
MyRunable myRunable=new MyRunable();
new Thread(myRunable).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myRunable.setRun(false);
::::runing.......
::::runing.......
::::runing.......
::::runing.......
::::runing.......
执行完成::::false
使用自定义标记也可以来停止线程,那和线程提供的方法有什么不一样的呢?
加入我们的run方法逻辑中有阻塞方法时候
class Mythread extends Thread{
boolean isRun=true;
public boolean isRun() {
return isRun;
}
public void setRun(boolean run) {
isRun = run;
}
@Override
public void run() {
super.run();
while (isRun()){
try {
Thread.sleep(4000);
System.out.println("::::runing.......");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("执行完成::::"+isRun()); //true
}
}
Mythread mythread=new Mythread();
mythread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mythread.setRun(false);
加入sleep方法之后,发现在线程休眠的时候调用的mythread.setRun(false);
线程不会马上停止,会等到休眠时间到了执行完run方法之后,才会停止
3、使用线程的 stop、suspend、resume 方法
以上三个是thread 提供的方法,但是现在被标注过期,不建议 使用,是因为使用以上方法,停止线程系统不会释放线程所占有的资源,因为没有给线程释放资源的机会和时间,会引起其他问题,所以不建议使用。