1、代码示例
public static void main(String[] args) throws Exception {
Thread t = new Thread(new Runnable() {
private Integer count = 1;
@Override
public void run() {
//如果发现中断标志,就停止运行
while (true && !Thread.currentThread().isInterrupted()){
try{
count++;
if(count > 200){
count =1000;
}
Thread.sleep(2000);
}catch (InterruptedException e){
//发生中断之后,继续执行
//System.out.println("发生中断之后,结束运行");
//break;
System.out.println("中断发生后的中断状态"); //其实就是基于状态机的线程生命周期控制
//收到InterruptedException之后,线程的中断状态会被清除,此时的中断标志位false。
System.out.println(Thread.currentThread().isInterrupted());
//Thread.currentThread().interrupt(); 会把中断标志置为true
Thread.currentThread().interrupt();
System.out.println("调用完interrupt方法之后");
System.out.println(Thread.currentThread().isInterrupted());
//return
}
}
}
});
t.start();
Thread.sleep(1000);
System.out.println("主线程睡眠结束,开始中断");
t.interrupt();
Thread.State state = t.getState();
System.out.println(state);
}
2、如何处理中断
当发生中断异常时,我们有几种处理手段:
-
不捕获InterruptedException ,而把其传播给调用者来处理
-
捕获InterruptedException,执行特定的清理动作,并 rethrowing InterruptedException
-
捕获InterruptedException,记录中断日志,并恢复中断标志
-
捕获InterruptedException,并吃掉它 (不要这样做)
2.1 不捕获InterruptedException ,而把其传播给调用者来处理
public class TaskQueue {
private static final int MAX_TASKS = 1000;
private BlockingQueue<Task> queue
= new LinkedBlockingQueue<Task>(MAX_TASKS);
public void putTask(Task r) <strong>throws InterruptedException</strong> {
queue.put(r);
}
public Task getTask() <strong>throws InterruptedException</strong> {
return queue.take();
}
}
2.2 捕获InterruptedException执行特定的清理动作并rethrowing InterruptedException
public class PlayerMatcher {
private PlayerSource players;
public PlayerMatcher(PlayerSource players) {
this.players = players;
}
public void matchPlayers() <strong>throws InterruptedException</strong> {
Player playerOne, playerTwo;
try {
while (true) {
playerOne = playerTwo = null;
// Wait for two players to arrive and start a new game
playerOne = players.waitForPlayer(); // could throw IE
playerTwo = players.waitForPlayer(); // could throw IE
startNewGame(playerOne, playerTwo);
}
}
catch (InterruptedException e) {
// If we got one player and were interrupted, put that player back
if (playerOne != null)
players.addFirst(playerOne);
// Then propagate the exception
<strong>throw e;</strong>
}
}
}
2.3 捕获InterruptedException,记录中断日志,并恢复中断标志
public class TaskRunner implements Runnable {
private BlockingQueue<Task> queue;
public TaskRunner(BlockingQueue<Task> queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException e) {
// Restore the interrupted status
<strong>Thread.currentThread().interrupt();</strong>
}
}
}
2.4 捕获InterruptedException并吃掉它 (错误的做法)
// Don't do this
public class TaskRunner implements Runnable {
private BlockingQueue<Task> queue;
public TaskRunner(BlockingQueue<Task> queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException swallowed) {
/* DON'T DO THIS - RESTORE THE INTERRUPTED STATUS INSTEAD */
}
}
}
3、参考文献
3.1 处理中断IBM
网友评论