当前位置: 首页 > 后端技术 > Java

如何正确中断线程?你的姿势正确了吗

时间:2023-04-01 23:57:42 Java

Java停止线程的逻辑(协调、通知)在Java程序中,我们想要停止一个线程,我们可以通过interrupt方法来停止它。但是当我们调用中断方法的时候,它可能不会立即停止线程,而是通知线程需要停止。线程收到通知后,会根据自身情况判断是否需要停止。它可能立即停止,可能执行一段时间后停止,也可能根本不停止。那么Java为什么要选择这种非强制线程中断呢?其实更多的是为了数据安全,为了保证程序的健壮性。因为我们不知道程序在做什么。如果贸然停止,可能会造成数据混乱和不完整。一个简单的例子:publicclass_24_ThreadTestimplementsRunnable{@Overridepublicvoidrun(){intcount=0;while(!Thread.currentThread().isInterrupted()&&count<=2000){System.out.println("count:"+count++);}}publicstaticvoidmain(String[]args)throwsException{_24_ThreadTestthreadTest=new_24_ThreadTest();线程thread=newThread(threadTest);thread.start();线程.睡眠(10);//中断线程thread.interrupt();}}这个例子是一个简单的通过interrupt中断线程的例子。run方法通过判断当前线程是否被中断以及count是否大于2000来循环,如果线程被中断,则退出循环,线程执行结束。这是线程正常停止的情况。Sleep是否会收到线程中断信号publicclass_24_ThreadTestimplementsRunnable{@Overridepublicvoidrun(){intcount=0;while(!Thread.currentThread().isInterrupted()&&count<=2000){try{System.out.println("计数:"+count++);//子线程睡眠Thread.sleep(1000*2);System.out.println("方法体:"+Thread.currentThread().isInterrupted());}catch(InterruptedExceptione){System.out.println("异常:"+Thread.currentThread().isInterrupted());//线程中断标志重置为假e.printStackTrace();}}}publicstaticvoidmain(String[]args)throwsException{_24_ThreadTestthreadTest=new_24_ThreadTest();线程thread=newThread(threadTest);thread.start();线程.睡眠(10);//中断线程thread.interrupt();}}如果在子线程中休眠,主线程通过interrupt方法中断,子线程还能接收到中断信号吗?其实在这种情况下,线程也可以收到信号通知。这时会抛出InterruptedException,线程中断标志位会被置为false。抛出异常后,线程标志被设置为false,所以如果下一次循环判断计数不为false,仍然可以进入循环体。这个时候线程是不能停止的。执行结果:案例场景:当通过线程运行一些后台任务时,如果循环中遇到线程中断异常,我们需要终止当前任务,并告诉客户端当前任务执行失败的记录。在这种情况下,可以通过在异常中再次中断来停止线程,并返回给客户端当前发生异常的记录。而不是继续执行。解决方法publicclass_24_ThreadTestimplementsRunnable{@Overridepublicvoidrun(){intcount=0;while(!Thread.currentThread().isInterrupted()&&count<=2000){try{System.out.println("count:"+count++);//子线程序睡眠Thread.sleep(1000*2);Thread.currentThread().interrupt();System.out.println("方法体:"+Thread.currentThread().isInterrupted());}catch(InterruptedExceptione){//再次中断Thread.currentThread().interrupt();System.out.println("异常:"+Thread.currentThread().isInterrupted());e.printStackTrace();}}}publicstaticvoidmain(String[]args)throwsException{_24_ThreadTestthreadTest=new_24_ThreadTest();线程thread=newThread(threadTest);thread.start();吨hread.sleep(10);//中断线程thread.interrupt();}}既然我们已经知道线程中断异常发生后线程中断标志会被重置为false,那么我们可以在异常中再次手动重置中断当前线程,那么就可以完全停止线程任务总结上面我们简单的介绍了如何正确停止线程。如果在以后的面试中被问到这样的问题,你能不能顺利的回答面试官。在run方法中遇到异常,我们不能直接吞掉。我们必须处理它。您可以进行简单的日志记录或中断线程。但就是不能无所作为。其实还有其他的停止线程的方法,比如stop(),已经被废弃了。这种强制停止可能会导致线程的数据安全问题,不再推荐使用。