interrupted()和isInterrupted()比较
Posted 二十年后20
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了interrupted()和isInterrupted()比较相关的知识,希望对你有一定的参考价值。
interrupted():测试当前线程【运行此方法的当前线程】是否已经是中断状态,执行后具有将状态标志清除为false的功能。
isInterrupted():测试线程对象是否已经是中断状态,但不清除状态标志。
interrupted()的例子:
public static void main(String[] args) { try{ MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); thread.interrupt(); syso(thread.interrupted()); syso(thread.interrupted()); }catch(InterruptedException e) { e.printStackTrace(); } } //运行结果 false false
从上可以看出thread.interrupted()执行的是运行当前方法的线程,而不是thread线程,而由于main线程一直没有停止,所以一直是false。
public static void main(String[] args) { Thread.currentThread().interrupt(); syso(Thread.interrupted()); syso(Thread.interrupted()); } //运行结果 true false
从上可以看出Thread.currentTrhead().interrupt()将main线程停止了,所以下面第一个是true状态,而第二个是false状态,就是因为interrupted()方法有清空状态标志的功能。
isInterrupted()的例子:
public static void main(String[] args) { try{ MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); thread.interrupt(); syso(thread.isInterrupted()); syso(thread.isInterrupted()); }catch(InterruptedException e) { e.printStackTrace(); } } //运行结果 true true
从上面可以看出isInterrupted()就是线程对象是否中断。
interrupt()并不能真正的结束线程:
public class MyThread extends Thread{ public void run() { super.run(); for(int i = 0; i < 5; i++) { if(this.interrupted()) { System.out.println("已经是停止状态了!我要退出了!"); break; } System.out.println("i = " + i); } System.out.println("for之后代码"); } } public class Main { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(2000); thread.interrupt(); } catch(InterruptedException e) { e.printStackTrace(); } System.out.println("结束了"); } }
运行结果:
可以发现interrupt()并没有真正终止线程。下面介绍几种可以终止线程的方法:
1.异常法【建议使用】:
if(this.interrupted()) { System.out.println("已经是停止状态了!我要退出了!"); throw new InterruptedException(); break; }
在上面需要正常终止的地方抛出异常即可。
此方法最推荐使用,因为在catch块中还可以将异常向上抛,使线程停止的事件得以传播。
2.在sleep中interrupt():
public class SleepThread extends Thread{ public void run() { super.run(); try { System.out.println("run begin"); Thread.sleep(200000); System.out.println("run end"); } catch(InterruptedException e) { System.out.println("沉睡中停止,进入catch"); e.printStackTrace(); } } } public class SleepMain { public static void main(String[] args) { try { SleepThread thread = new SleepThread(); thread.start(); Thread.sleep(200); thread.interrupt(); } catch(InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("结束了"); } }
运行结果:
3.使用作废的stop()方法:
调用stop()方法会强制让线程停止则有可能使一些清理性的工作得不到完成。并且有可能对锁定对象进行了“解锁”,导致数据得不到同步处理,出现数据不一致问题。
4.return法:
public class ReturnThread extends Thread{ public void run() { while(true) { if(this.isInterrupted()) { System.out.println("停止了!"); return; } System.out.println("timer" + System.currentTimeMillis()); } } } public class ReturnMain { public static void main(String[] args) throws InterruptedException { ReturnThread thread = new ReturnThread(); thread.start(); Thread.sleep(20); thread.interrupt(); } }
在需要停止的地方return即可。
暂停线程所使用的suspend()和resume()已经弃用,这里看一下suspend()方法:
当某个线程的suspend()方法被调用时,该线程会被挂起。如果该线程占有了锁,则它不会释放锁。即,线程在挂起的状态下还持有锁。
public class MyThread extends Thread{ private long i = 0; public void run() { while(true) { i++; //syso是一个同步方法 System.out.println(i); } } } public class Main { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start();//启动一个线程\'thread\' Thread.sleep(1000);//使当前线程(main线程)睡眠 thread.suspend();//挂起线程\'thread\' //下面这一行不会执行,因为println一直被占用 System.out.println("main end!"); } catch (InterruptedException e) { e.printStackTrace(); } } }
下面看一下println()源码:
public void println(long x) { synchronized (this) { print(x); newLine(); } }
从上可以看出suspend()暂停线程之后不会释放锁。
而在main中调用resume(),可以恢复线程,线程执行完毕就会释放锁。
以上是关于interrupted()和isInterrupted()比较的主要内容,如果未能解决你的问题,请参考以下文章
interrupt, isInterrupted, interrupted
java interrupted与isInterrupted方法
interrupt ,interrupted 和 isInterrupted
为啥在实现 Runnable 时使用 Thread.currentThread().isInterrupted() 而不是 Thread.interrupted()?