interrupt进程终止
interrupt()源码
/**
* Interrupts this thread.
*
* <p> Unless the current thread is interrupting itself, which is
* always permitted, the {@link #checkAccess() checkAccess} method
* of this thread is invoked, which may cause a {@link
* SecurityException} to be thrown.
*
* <p> If this thread is blocked in an invocation of the {@link
* Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
* Object#wait(long, int) wait(long, int)} methods of the {@link Object}
* class, or of the {@link #join()}, {@link #join(long)}, {@link
* #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
* methods of this class, then its interrupt status will be cleared and it
* will receive an {@link InterruptedException}.
*
* <p> If this thread is blocked in an I/O operation upon an {@link
* java.nio.channels.InterruptibleChannel InterruptibleChannel}
* then the channel will be closed, the thread's interrupt
* status will be set, and the thread will receive a {@link
* java.nio.channels.ClosedByInterruptException}.
*
* <p> If this thread is blocked in a {@link java.nio.channels.Selector}
* then the thread's interrupt status will be set and it will return
* immediately from the selection operation, possibly with a non-zero
* value, just as if the selector's {@link
* java.nio.channels.Selector#wakeup wakeup} method were invoked.
*
* <p> If none of the previous conditions hold then this thread's interrupt
* status will be set. </p>
*
* <p> Interrupting a thread that is not alive need not have any effect.
*
* @throws SecurityException
* if the current thread cannot modify this thread
*
* @revised 6.0
* @spec JSR-51
*/
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
我主要强调一点当线程处于阻塞状态的时候,调用interrupt(),interrupt status 状态会被clear,从true再次变为false。所以对于通过InterruptedException异常
来中断需要正确的try catch语句。
正确的阻塞线程中断方式
package com.java.javabase.thread.base;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class InterruptTest2 {
public static void main(String[] args) {
InterruptTest2 test = new InterruptTest2();
Thread t1 = test.new ThreadOne("t1");
t1.start();
try {
Thread.sleep(2000);
t1.interrupt();
log.info("Thread t1 state :{} ", t1.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
class ThreadOne extends Thread {
public ThreadOne(String name) {
super(name);
}
@Override
public void run() {
int i = 0;
try {
while (!interrupted()) {
Thread.sleep(500);
log.info("Thread {} state :{} ,run {} times", Thread.currentThread().getName(),
Thread.currentThread().getState(), i++);
}
} catch (InterruptedException e) {
log.info("Thread {} state :{} ,run {} times", Thread.currentThread().getName(),
Thread.currentThread().getState(), i++);
e.printStackTrace();
}
}
}
}
返回结果
2019-07-30 19:52:40,496 [t1] INFO InterruptTest2 - Thread t1 state :RUNNABLE ,run 0 times
2019-07-30 19:52:41,000 [t1] INFO InterruptTest2 - Thread t1 state :RUNNABLE ,run 1 times
2019-07-30 19:52:41,500 [t1] INFO InterruptTest2 - Thread t1 state :RUNNABLE ,run 2 times
2019-07-30 19:52:41,991 [main] INFO InterruptTest2 - Thread t1 state :TIMED_WAITING
2019-07-30 19:52:41,991 [t1] INFO InterruptTest2 - Thread t1 state :RUNNABLE ,run 3 times
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.java.javabase.thread.base.InterruptTest2$ThreadOne.run(InterruptTest2.java:36)
说明
while语句在try catch 捕获到InterruptedException异常,就可以处理。
错误的中断阻塞线程例子
package com.java.javabase.thread.base;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class InterruptTest {
public static void main(String[] args) {
InterruptTest test = new InterruptTest();
Thread t1 = test.new ThreadOne("t1");
t1.start();
try {
Thread.sleep(2000);
t1.interrupt();
log.info("Thread state :{} ", t1.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
class ThreadOne extends Thread {
public ThreadOne(String name) {
super(name);
}
@Override
public void run() {
int i = 0;
while (!interrupted()) {
try {
Thread.sleep(500);
log.info("Thread {} state :{} ,run {} times", Thread.currentThread().getName(),
Thread.currentThread().getState(), i++);
} catch (InterruptedException e) {
log.info("Thread {} state :{} ,run {} times", Thread.currentThread().getName(),
Thread.currentThread().getState(), i++);
e.printStackTrace();
}
}
}
}
}
测试结果
2019-07-30 19:54:40,189 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 0 times
2019-07-30 19:54:40,691 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 1 times
2019-07-30 19:54:41,192 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 2 times
2019-07-30 19:54:41,686 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 3 times
2019-07-30 19:54:41,686 [main] INFO InterruptTest - Thread state :TIMED_WAITING
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.java.javabase.thread.base.InterruptTest$ThreadOne.run(InterruptTest.java:35)
2019-07-30 19:54:42,187 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 4 times
2019-07-30 19:54:42,687 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 5 times
2019-07-30 19:54:43,187 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 6 times
2019-07-30 19:54:43,687 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 7 times
2019-07-30 19:54:44,187 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 8 times
2019-07-30 19:54:44,687 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 9 times
2019-07-30 19:54:45,187 [t1] INFO InterruptTest - Thread t1 state :RUNNABLE ,run 10 times
错误结果说明
try catch在while语句之内, 捕获到InterruptedException异常,while的!interrupted()会再次返回true
运行态的线程的终止
package com.java.javabase.thread.base;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class InterruptTest3 {
private boolean stopFlag = false;
private void stoptask() {
this.stopFlag = true;
}
public static void main(String[] args) {
InterruptTest3 test = new InterruptTest3();
Thread t1 = test.new ThreadOne("t1");
t1.start();
try {
Thread.sleep(5000);
test.stoptask();
log.info("Thread t1 state :{} ", t1.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
class ThreadOne extends Thread {
public ThreadOne(String name) {
super(name);
}
int i = 0;
@Override
public void run() {
while (!stopFlag) {
try {
sleep(1000);
log.info("Thread {} state :{} ,run {} times", Thread.currentThread().getName(),
Thread.currentThread().getState(), i++);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
测试结果
2019-07-30 20:01:19,922 [t1] INFO InterruptTest3 - Thread t1 state :RUNNABLE ,run 0 times
2019-07-30 20:01:20,923 [t1] INFO InterruptTest3 - Thread t1 state :RUNNABLE ,run 1 times
2019-07-30 20:01:21,923 [t1] INFO InterruptTest3 - Thread t1 state :RUNNABLE ,run 2 times
2019-07-30 20:01:22,923 [t1] INFO InterruptTest3 - Thread t1 state :RUNNABLE ,run 3 times
2019-07-30 20:01:23,918 [main] INFO InterruptTest3 - Thread t1 state :TIMED_WAITING
2019-07-30 20:01:23,923 [t1] INFO InterruptTest3 - Thread t1 state :RUNNABLE ,run 4 times