线程的suspend、resume方法暂停的时间点不可控,也早就不推荐使用.
可以通过interrupt实现线程安全的暂停、恢复.
可以把中断标志位当做一个普通的属性,程序可以相应,可以中断线程,也可以不中断.
所以不建议使用额外定义的一个volatile变量来控制线程的停止,包括lock类的lockInterruptibly也都很好的支持了Interrupt.
主要方法有
interrupt-设置中断标志位;sleep、wait中检测到该标志位,清空该标志位后抛出InterruptedException
interrupted-检测中断标志位,如果标志位位true、清空标志位
isInterrupted-检测中断标志位
个人理解清空标志位,即表示此处会做处理,后面无须知道中断标志位,也无须处理中断。
实际对于耗时高、可能中止的方法,都应该检测该标志位.
示例代码
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
long i = 0;
while (i++ < Long.MAX_VALUE) {
if (Thread.interrupted()) {// will clear interrupted flag at the same time
System.out.println(“although interrupted, but will continue. current i:” + i);
for (int j = 0; j < 1000000000; j++)
;
}
if (i % 100000000 == 0) {
System.out.println(“thread1 i:” + (i / 100000000));
}
}
});
thread1.start();
Thread.sleep(3000L);
thread1.interrupt();
Thread.sleep(3000L);
//thread1.join();
thread1.stop();//deprecated,only for test
Thread suspendAbleTestThead = new Thread(new SuspendAbleTest());
suspendAbleTestThead.start();
Thread.sleep(3000L);
suspendAbleTestThead.interrupt();
Thread.sleep(5000L);
suspendAbleTestThead.interrupt();
suspendAbleTestThead.join();
}
public static class SuspendAbleTest implements Runnable {
private long i;
private boolean suspendedFlag = false;
@Override
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) {
suspendedFlag = !suspendedFlag;
}
try {
while (suspendedFlag) {
Thread.sleep(1000L);
}
System.out.println(“SuspendAbleTest:” + (i++));
Thread.sleep(1000L);// when interrupted will clear interrupted flag
} catch (InterruptedException ite) {
suspendedFlag = !suspendedFlag;
}
}
}
}
输出
thread1 i:1
thread1 i:2
although interrupted, but will continue. current i:213697503
thread1 i:3
SuspendAbleTest:0
SuspendAbleTest:1
SuspendAbleTest:2
SuspendAbleTest:3
SuspendAbleTest:4
SuspendAbleTest:5
SuspendAbleTest:6
SuspendAbleTest:7
SuspendAbleTest:8
SuspendAbleTest:9
SuspendAbleTest:10