看下面的代码,这个程序大概运行一秒钟后就会中断,使用volatile类型的变量来保存取消状态
package com.thred;
public class InterruptTest {
public static void main(String[] args) {
Worker2 worker = new Worker2();
worker.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
worker.shutdown();
}
}
class Worker2 extends Thread {
volatile boolean flag = true;
@Override
public void run() {
while (flag) {
System.out.println("work");
}
}
public void shutdown() {
flag = false;
}
}
接着再看下面的代码:
package com.thred;
public class InterruptTest {
public static void main(String[] args) {
Worker2 worker = new Worker2();
worker.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
worker.shutdown();
}
}
class Worker2 extends Thread {
volatile boolean flag = true;
@Override
public void run() {
while (flag) {
System.out.println("work");
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void shutdown() {
flag = false;
}
}
用上面那种方式调用shutdown方法来取消线程已经不起效了,因为在线程中调用阻塞方法sleep,这个线程会一直运行下去直到休眠结束。这时我们就得利用线程的中断机制来取消线程,Thread中的中断方法:
public class Thread{
public void interrupt(){...}
public boolean isInterrupted(){...}
public static boolean interrupted(){...}
}
阻塞库方法,例如Thread.sleep和Object.wait等,都会检查线程何时中断,并且在发现中断时返回。它们在相应中断时执行的操作包括:清除中断状态,抛出InterruptException,表示由于阻塞操作提前结束。jvm不能保证阻塞方法检测到中断的速度,这要取决于你本机的jvm,实际情况响应速度还是挺快的。接下来我们把代码改成如下:调用shutdonw方法线程会立即中断并抛出InterruptException,我们可以在异常中重置取消变量为false来取消线程运行.
package com.thred;
public class InterruptTest {
public static void main(String[] args) {
Worker2 worker = new Worker2();
worker.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
worker.shutdown();
}
}
class Worker2 extends Thread {
volatile boolean flag = true;
@Override
public void run() {
while (flag) {
System.out.println("work");
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
flag = false;//重置取消状态
}
}
}
public void shutdown() {
this.interrupt();
}
}