前言:Java提供了3种终止正在运行的线程的方法
a、使用推出标志,使线程正常退出,也就是在run方法完成后线程自然终止
b、使用interrupt方法中断线程
c、使用stop方法强行终止线程,不推荐(过期作废)
以下主要介绍第二种方法,使用interrupt方法。
大多数停止一个线程都会使用 Thread.interrupt() 方法,但是很这个方法不会终止正在运行的线程,需要加入一个判断才可以完成线程的停止。
示例1:
MyThread.java
public class MyThread extends Thread{
@Override
public void run(){
super.run();
for (int i=0;i<500000;i++){
System.out.println("i=" + (i+1));
}
}
}
Run.java
public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
thread.sleep(2000);
thread.interrupt();
}catch (InterruptedException e){
System.out.println("main catch");
e.printStackTrace();
}
}
}
运行Run后会发现,输出还是有500000行,说明interrupt方法并没有让线程终止。
怎么判断线程是否是停止状态?
Thread.java提供了了两种方法判断线程是不是停止的。
a、判断当前线程是否已经中断 this.interrupted(); (public static boolean interrupted() )
b、判断线程是否已经中断 this.isInterrupted(); ( public boolean sInterrupted() )
示例a-1:线程实例产生中断效果
Run1.java
public class Run1 {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
thread.sleep(1000);
thread.interrupt();
System.out.println("1是否停止? = " + thread.interrupted());
System.out.println("2是否停止? = " + thread.interrupted());
}catch (InterruptedException e){
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end");
}
}
输出结果中,两次 thread.interrupted() 都为 false
原因是,当前线程指的是main,500000次输出还没执行完毕,即使调用了 thread.interrupted(),线程还是没终止,所以返回值都是false。
示例a-2: 让main线程产生中断效果
Run2.java
public class Run2 {
public static void main(String[] args) {
Thread.currentThread().interrupt();
System.out.println("1是否停止? = " + Thread.interrupted());
System.out.println("2是否停止? = " + Thread.interrupted());
System.out.println("end");
}
}
输出结果中,第一个 Thread.interrupted() 为 true,第二个 Thread.interrupted() 为 false
原因是,interrupted 方法具有清除状态的功能,即连续调用两次第二次会返回false。
示例b-1:使用isInterrupted方法
public class Run3 {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
thread.sleep(1000);
thread.interrupt();
System.out.println("1是否停止? = " + thread.isInterrupted());
System.out.println("2是否停止? = " + thread.isInterrupted());
}catch (InterruptedException e){
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end");
}
}
在500000行输出中间打印出 两个 true 和 end
方法isInterrupted没有清除状态,所以两个都是true
总结:
1)this.interrupted() : 测试当前线程是否已经是中断状态,执行后将状态标志清除,置为false。
2)this.isinterrupted() : 测试线程Thread对象是否已经是中断状态,但不清除状态标志。
示例一:在线程for循环中加入判断,判断是否为停止状态,若是,则break让for循环不再执行
stopThread.java
public class stopThread extends Thread {
@Override
public void run(){
super.run();
for (int i=0;i<500000;i++){
if (this.isInterrupted()) {
System.out.println("停止状态,我要退出了别拉着我!");
break;
}
System.out.println("i=" + (i+1));
}
}
}
RunStop.java
public class RunStop {
public static void main(String[] args) {
try{
stopThread sThread = new stopThread();
sThread.start();
Thread.sleep(2000);
sThread.interrupt();
}catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
输出结果为:
这种方式退出线程只是跳出循环,for循环后面的代码还是会继续循环。
示例二:异常法
stopThread.java
public class stopThread extends Thread {
@Override
public void run(){
super.run();
try {
for (int i=0;i<500000;i++){
if (this.isInterrupted()) {
System.out.println("停止状态,我要抛出异常了!!");
throw new InterruptedException();
}
System.out.println("i=" + (i+1));
}
}catch (InterruptedException e) {
System.out.println("进入stopThread类中run方法的catch");
e.printStackTrace();
}
}
}
runStop.java
public class RunStop {
public static void main(String[] args) {
try{
stopThread sThread = new stopThread();
sThread.start();
Thread.sleep(2000);
sThread.interrupt();
}catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
输出结果:
--------------未完,待续。