停止一个线程意味着在线程处理完任务之前停掉正在做的操作,也就是放弃当前的操作。虽然这看起来非常简单,但是必须做好防范措施,以便达到预期的效果。
停止一个线程可以使用Thread.stop();但是最好不要用它,因为这个方法不是安全的,而且已经被废用了,因为如果强制让线程停止则有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了‘解锁’,导致数据得不到同步的处理,出现数据不一致的问题。
大多数停止一个线程的操作使用的是Thread.interrupt()方法,这个方法不会终止一个正在运行的线程,仅仅是在当前线程中打上了一个停止的标记,它还需要加入一个判断才可以完成线程的停止。
停止线程大致有三种方式:(1)当run()方法执行完后线程正常终止。(2)Thread.stop();(3)Thread.interrupt()
判断线程是否是停止状态的方法:
Thread.interrupted();//测试当前线程是否已经中断状态,执行完后具有将状态标志清除为false的功能
threadObj.isInterrupted();//测试线程Thread对象是否已经中断,但不清除状态标志
@Override
public void run() {
for (int i = 0; i < 20000; i++) {
System.out.println(i);
}
System.out.println("END");
}
}
public class Test {
public static void main(String[] args) {
InterruptThread it = new InterruptThread();
it.start();
it.interrupt();
System.out.println("main end");
System.out.println("线程结束标记:" + it.isInterrupted());
}
}
image.png
由此可见Thread.interrupt()未将其线程终止,仅仅是在当前线程中打上了一个停止的标记。
异常法停止线程
@Override
public void run() {
try {
for (int i = 0; i < 2000000; i++) {
System.out.println(i);
if (this.isInterrupted()) {
System.out.println("线程停止,立即退出!");
throw new InterruptedException();
}
}
System.out.println("END");
} catch (InterruptedException e) {
System.out.println("InterruptThread run catch");
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) {
InterruptThread it = new InterruptThread();
it.start();
it.interrupt();
System.out.println("main end");
System.out.println("线程结束标记:" + it.isInterrupted());
}
}
image.png
由于InterruptThread 类中的END并没有输出,所以由此可见在线程中断标记后,子线程停止
在沉睡中停止
线程在sleep()状态下停止线程(先sleep再Interrupt)
@Override
public void run() {
try {
System.out.println("run begin");
Thread.sleep(1000);
System.out.println("run end");
} catch (InterruptedException e) {
System.out.println("在沉睡中被停止:" + this.isInterrupted());
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) {
//先沉睡再interrupt()
InterruptThread it = new InterruptThread();
it.start();
it.interrupt();
System.out.println("main end");
}
}
image.png
从打印的结果来看在sleep()状态下停止某一线程,会进入catch语句,并会清除标记的停止状态,使之变成false
先Interrupt再sleep
@Override
public void run() {
try {
for (int i = 0; i < 200000; i++) {
System.out.println(i);
}
System.out.println("run begin");
Thread.sleep(1000);
System.out.println("run end");
} catch (InterruptedException e) {
System.out.println("在沉睡中被停止:" + this.isInterrupted());
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) {
//先沉睡再interrupt()
InterruptThread it = new InterruptThread();
it.start();
it.interrupt();
System.out.println("main end");
}
}
image.png
由此可见无论是先sleep再Interrupt亦或者先Interrupt再sleep,都会进入catch语句,并会清除标记的停止状态,使之变成false
网友评论