中断在java中主要有3个方法,interrupt(),isInterrupted()和interrupted()。
interrupt(),在一个线程中调用另一个线程的interrupt()方法,即会向那个线程发出信号——线程中断状态已被设置。至于那个线程何去何从,由具体的代码实现决定。
isInterrupted(),用来判断当前线程的中断状态(true or false)。
interrupted()是个Thread的static方法,用来恢复中断状态。
先了解Sleep用法:
sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会。
public class SleepDemo {
public static void main(String args[]) {
try {
System.out.println(new Date( ) + "\n");
Thread.sleep(1000*3); // 休眠3秒
System.out.println(new Date( ) + "\n");
} catch (Exception e) {
System.out.println("Got an exception!");
}
}
}
输出:
Fri Aug 02 13:16:19 CST 2019
Fri Aug 02 13:16:22 CST 2019
注意:
1、线程睡眠是帮助所有线程获得运行机会的最好方法。
2、线程睡眠到期自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。
3、sleep()是静态方法,只能控制当前正在运行的线程。
interrupt()不能中断在运行中的线程,它只能改变中断状态而已
public class InterruptionInJava implements Runnable{
public static void main(String[] args) throws InterruptedException {
Thread testThread = new Thread(new InterruptionInJava(),"InterruptionInJava");
//start thread
testThread.start();
//interrupt thread
testThread.interrupt();
System.out.println("main end");
}
@Override
public void run() {
while(true){
if(Thread.currentThread().isInterrupted()){
System.out.println("Yes,I am interruted,but I am still running");
}else{
System.out.println("not yet interrupted");
}
}
}
}
会输出:
main end
Yes,I am interruted,but I am still running
Yes,I am interruted,but I am still running
Yes,I am interruted,but I am still running
.......... (无限)
package com.fosu.interrupt;
public class ExceptionInterrupt 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));
}
System.out.println("我被输出,如果此代码是for又继续运行,线程并未停止!");
}
public static void main(String[] args) {
ExceptionInterrupt thread = new ExceptionInterrupt();
thread.start();
try {
Thread.sleep(2000); // 主线程
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end!");
}
}
i=1
... ...
i=283090
i=283091
已经是停止状态了!我要退出了!
我被输出,如果此代码是for又继续运行,线程并未停止!
end!
我们发现,上面的示例虽然停止了线程,但是如果for语句下面还有语句,那么还是会继续执行。
所以我们这里用异常法来停止线程,就不会继续执行for后面的业务逻辑了。
public class ExceptionInterrupt2 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));
}
System.out.println("我在for下面");
} catch (InterruptedException e) {
System.out.println("进入ExceptionInterrupt2 类中run方法的catch了!");
e.printStackTrace();
}
}
public static void main(String[] args) {
ExceptionInterrupt2 thread = new ExceptionInterrupt2();
thread.start();
try {
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
可参考博客:https://www.ibm.com/developerworks/cn/java/j-jtp05236.html#ibm-pcon
https://www.cnblogs.com/jenkov/p/juc_interrupt.html (interrupt)
https://blog.csdn.net/zxl_LangYa/article/details/82662919
https://www.cnblogs.com/kaituorensheng/p/9795454.html(sleep与wait区别)