在Java中停止线程的三种方法
(1)正常退出,run方法运行完毕后线程正常终止
(2)使用stop方法强行终止,但是该方法同suspend和resume方法一样, 已经过期作废。
(3)使用interrupt方法中断线程
中断不了的线程-interrupt方法
调用interrupt方法只是在当前线程打了一个终止的标记,不是真的停止线程的运行
如下例所示:
public class ThreadTest{
public static void main(String[] args){
try {
MyThread myThread = new MyThread();
myThread.start();
MyThread.sleep(1000);
myThread.interrupt();
System.out.println(Thread.currentThread().getName()+"---"+Thread.interrupted());
System.out.println(Thread.currentThread().getName()+"---"+Thread.interrupted());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
class MyThread extends Thread{
@Override
public void run() {
super.run();
for(int i=0;i<1000;i++){
System.out.println("i = "+i);
}
}
}
运行结果如下(并没有停止线程):
上面打印俩个false的原因是main线程未停止,所以打印俩个false
interrupt()方法和isInterrupt()方法
public class ThreadTest{
public static void main(String[] args){
/*MyThread myThread = new MyThread();
myThread.start();
MyThread.sleep(1000);*/
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().getName()+"---"+Thread.interrupted());
System.out.println(Thread.currentThread().getName()+"---"+Thread.interrupted());
}
}
运行结果(原因是:interrupt方法:测试当前线程是否是中断状态,但是会清除中断的标记状态,如果连续俩次调用该方法,第一次会将中断的状态标记会清除掉,所以第二次为false):
main—true
main—false
Process finished with exit code 0
public class ThreadTest{
public static void main(String[] args){
/*MyThread myThread = new MyThread();
myThread.start();
MyThread.sleep(1000);*/
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().getName()+"---"+Thread.currentThread().isInterrupted());
System.out.println(Thread.currentThread().getName()+"---"+Thread.currentThread().isInterrupted());
}
}
运行结果如下(原因是:isInterrupted方法测试当前线程是否是中断状态,但不清楚中断状态标记):
main—true
main—true
Process finished with exit code 0
能停止线程的方法-异常
public class ThreadTest{
public static void main(String[] args){
try {
MyThread myThread = new MyThread();
myThread.start();
MyThread.sleep(2000);
myThread.interrupt();
System.out.println("运行结束");
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
class MyThread extends Thread{
@Override
public void run() {
super.run();
try {
for(int i=0;i<1000000;i++){
if(this.interrupted()){
System.out.println("当前线程已经interrupt了");
throw new InterruptedException();
}
System.out.println("i = "+i);
}
}catch (InterruptedException e){
e.printStackTrace();
System.out.println("进入run中的catch块中");
}
}
}
运行结果:
i = 262907
i = 262908
i = 262909
运行结束
当前线程已经interrupt了
java.lang.InterruptedException
进入run中的catch块中
at com.ky.tjk.api.controller.MyThread.run(ThreadTest.java:29)
使用stop()方法停止异常
public class ThreadTest implements Runnable{
private int count = 100000;
Lock lock = new ReentrantLock();
public static void main(String[] args)throws Exception{
ThreadTest threadTest = new ThreadTest();
Thread thread = new Thread(threadTest);
thread.start();
Thread.sleep(100);
thread.stop();
}
@Override
public void run() {
while (count > 0){
count--;
System.out.println(count);
}
}
}
运行结果(Stop会暴力停止,会对锁定的对象进行解锁,可能会导致数据到不到同步的处理,出现数据不一致的问题):
90085
90084
90083
90082
90081
90080
Process finished with exit code 0
使用return停止线程
public class ThreadTest{
private int count = 100000;
Lock lock = new ReentrantLock();
public static void main(String[] args)throws Exception{
MyThread myThread = new MyThread();
myThread.start();
myThread.sleep(100);
myThread.interrupt();
}
}
class MyThread extends Thread{
@Override
public void run() {
super.run();
while (true){
if(this.isInterrupted()){
System.out.println("线程终止");
return;
}
System.out.println("时间为:"+System.currentTimeMillis());
}
}
}
运行结果为:
时间为:1585126950526
时间为:1585126950526
时间为:1585126950526
时间为:1585126950531
时间为:1585126950531
线程终止
总结:
使用异常停止的效果最好,因为可以在catch块中抛出信息,还可以使线程挺值得事件得到传递