`
sw1982
  • 浏览: 511383 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

[bugfix]重新理解Thread的InterruptedException

阅读更多

在前面一篇blog中,错误理解了中断异常,还被评为新手贴,最近找时间认真理解了一下线程的这个异常,呵呵。:

原文在这里

 

下文部分内容来自dw上的一篇文章,已经贴在附件里面、。

 

下面通过一段代码来演示中断:

 

package thread;

/**
 * created on 2010-4-27下午04:32:40
 * 
 * @author weisong
 */
public class TestInterupt {
	public static void main(String[] args) throws InterruptedException {
		
		Th1 th = new Th1();
		th.start();

		Thread.sleep(2000);
		System.out.println("try to stop");
		th.interrupt();
	}

}

class Th1 extends Thread {
	public void run(){
		try {
			this.sleep(50000);
		} catch (InterruptedException e) {
			System.out.println("interrupted ");
			e.printStackTrace();
		}
	}
}

 这个简单的代码过程是:启动一个线程th,sleep50s, 然后在main线程中去中断掉它的阻塞状态,然后th就走到catch代码中。

 

现在最主要的关注点有两个:1.走到catch中,th这个线程命运如何?  2.如何处理这个InterruptedException 比较合理。

 

问题一:走到catch中,th这个线程命运如何。

在catch块代码执行完毕之后,th线程会马上终止掉!这个是合理的。当一个方法抛出 InterruptedException 时,它不仅告诉您它可以抛出一个特定的检查异常,而且还告诉您其他一些事情。例如,它告诉您它是一个阻塞(blocking)方法,如果您响应得当的话,它将尝试消除阻塞并尽早返回。 阻塞方法不同于一般的要运行较长时间的方法。一般方法的完成只取决于它所要做的事情,以及是否有足够多可用的计算资源(CPU 周期和内存)。而阻塞方法的完成还取决于一些外部的事件,例如计时器到期,I/O 完成,或者另一个线程的动作(释放一个锁,设置一个标志,或者将一个任务放在一个工作队列中)。一般方法在它们的工作做完后即可结束,而阻塞方法较难于预测,因为它们取决于外部事件。阻塞方法可能因为等不到所等的事件而无法终止,因此令阻塞方法可取消 就非常有用

 

那么也就不难理解, Thread.sleep()Object.wait() 为什么会抛出这个InterruptedException。目的就是支持中断取消机制;它允许一个线程请求另一个线程停止它正在做的事情。当一个方法抛出 InterruptedException 时,它是在告诉您,如果执行该方法的线程被中断,它将尝试停止它正在做的事情而提前返回,并通过抛出 InterruptedException 表明它提前返回。

 

问题二。我们如何去处理InterruptedException 

 

中断是一种协作机制。当一个线程中断另一个线程时,被中断的线程不一定要立即停止正在做的事情。相反,中断是礼貌地请求另一个线程在它愿意并且方便的时候停止它正在做的事情。有些方法,例如 Thread.sleep(),很认真地对待这样的请求,但每个方法不是一定要对中断作出响应。对于中断请求,不阻塞但是仍然要花较长时间执行的方法可以轮询中断状态,并在被中断的时候提前返回。您可以随意忽略中断请求,但是这样做的话会影响响应。

 

那么就产生下面几个应用情况了:

1. 不捕捉 InterruptedException,将它传播给调用者。向上抛出,自己不处理。

2. 在重新抛出 InterruptedException 之前执行特定于任务的清理工作(比如连接关闭之类)

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
             Thread.currentThread().interrupt();
         }
    }
}

 4.需要中断阻塞线程, 那么参考最上面的demo,直接走完catch流程不处理异常即可。

 

ps.不可中断的阻塞方法

并非所有的阻塞方法都抛出 InterruptedException。输入和输出流类会阻塞等待 I/O 完成,但是它们不抛出 InterruptedException,而且在被中断的情况下也不会提前返回。然而,对于套接字 I/O,如果一个线程关闭套接字,则那个套接字上的阻塞 I/O 操作将提前结束,并抛出一个 SocketExceptionjava.nio 中的非阻塞 I/O 类也不支持可中断 I/O,但是同样可以通过关闭通道或者请求 Selector 上的唤醒来取消阻塞操作。类似地,尝试获取一个内部锁的操作(进入一个 synchronized 块)是不能被中断的,但是 ReentrantLock 支持可中断的获取模式。

 

分享到:
评论

相关推荐

    JAVA InterruptedException

    1. **重新抛出异常**:如果你的代码不负责处理中断,可以选择将`InterruptedException`重新抛出,让上层调用者处理。 2. **捕获并处理**:如果你需要做一些清理工作,比如关闭文件流或释放资源,可以在`catch`块中...

    处理 InterruptedException1

    在 Java 语言中,有很多方法可以抛出 InterruptedException,例如 Thread.sleep() 和 Object.wait()。这些方法都是阻塞方法,它们的完成取决于外部事件,而不是简单地运行完成任务。InterruptedException 是一种检查...

    Java处理InterruptedException异常的理论与实践

    总的来说,理解并正确处理`InterruptedException`是编写健壮、响应性强的Java并发程序的关键。当你的代码调用了可能会抛出`InterruptedException`的方法时,应该考虑你的方法是否也需要处理中断,以便于实现可取消的...

    InterruptedException和interrup

    正确的做法是,在捕获到`InterruptedException`之后,应该清除中断状态(通过再次调用`Thread.currentThread().interrupt()`),并且考虑终止线程的工作或者做一些清理操作。 下面是一些处理`InterruptedException`...

    Android:Handler的post()方法和Thread的start()方法执行Thread的run()方法的区别

    } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Handler--&gt;"+Thread.currentThread().getId()); System.out.println("Handler--&gt;"+Thread.currentThread()....

    Java Thread用法 经典

    ### Java Thread用法详解 #### 一、Java线程基础概念与重要性 在Java编程语言中,线程是程序执行的基本单位之一,它能够帮助我们实现多任务...正确地理解和运用这些概念和技术,对于编写高效稳定的并发程序至关重要。

    Thread捕捉异常示例

    因此,理解如何在Thread中捕获并处理异常是非常重要的。 首先,我们来看一下Java中异常的基本概念。在Java中,异常是通过`try-catch`块来处理的。当在`try`块中发生异常时,控制流会立即跳转到相应的`catch`块,...

    多线程thread线程的理解

    9. **中断和异常**:线程可以通过`interrupt()`方法中断,其他线程可以检查`isInterrupted()`或`InterruptedException`来响应中断请求。理解和妥善处理中断是编写可控制的多线程程序的重要部分。 10. **守护线程...

    Java有两种实现多线程的方式:通过Runnable接口、通过Thread直接实现,请掌握这两种实现方式,并编写示例程序。

    这意味着,即使在代码中定义了明确的执行流程,实际运行时,线程可能会被中断和重新调度。 #### 四、线程同步机制 多线程环境下,多个线程共享资源时可能会出现数据不一致的问题。为了解决这个问题,Java提供了...

    为什么不鼓励使用 Thread.stop?

    `Thread.interrupt` 方法是一个比较安全的替代方案,它会设置线程的中断状态,并且许多阻塞方法(如 `Thread.sleep`, `Object.wait`)在被中断时会抛出 `InterruptedException`,使得线程可以捕获这个异常并进行必要...

    Java Thread Programming

    本资料“Java Thread Programming”由Paul Hyde提供,包含了关于Java线程编程的理论知识和实践代码,旨在帮助开发者深入理解和熟练掌握Java线程。 首先,我们来了解一下Java中线程的基本概念。在Java中,可以通过两...

    这是一个线程类(Thread

    总结,理解并熟练使用Java的`Thread`类和`Runnable`接口对于进行高效的并发编程至关重要。通过学习这些概念和方法,开发者可以更好地管理程序中的线程,实现多任务并行,提高程序的运行效率。同时,线程同步和通信...

    Thread类的interrupt(),interrupted(),isInterrupted()1

    在Java多线程编程中,理解`Thread`类中的`interrupt()`、`interrupted()`和`isInterrupted()`方法至关重要,因为它们与线程中断机制紧密相关。线程中断是Java提供的一种协作式中断机制,它并不强制结束线程,而是...

    JavaThread.pdf

    在实际编程中,正确理解和运用Java线程的创建、管理、同步、中断等机制是非常重要的,它们是构建稳定高效Java并发程序的基础。上述知识点涉及了Java线程编程的核心概念,是开发者必须掌握的技能。

    java Thread

    - `interrupt()`:标记线程为中断状态,不会立即停止线程,而是在线程检查中断状态时抛出`InterruptedException`。 - `isInterrupted()`:检查线程是否被中断。 - `Thread.currentThread().isInterrupted()`:...

    JavaThread中断机制共11页.pdf.zip

    Java线程中断机制是Java多线程编程中的一个重要概念,它允许程序在执行过程中通过某种方式通知线程停止其当前的活动,以便进行资源释放或流程控制。...理解和正确使用中断机制对于编写健壮的多线程应用至关重要。

    java线程Thread的实例

    Java线程是Java编程中的...通过实例学习,你可以更好地理解如何创建和管理线程,以及如何在多线程环境中处理同步和通信问题。这个实例对于初学者来说是一次宝贵的学习机会,能够帮助他们逐步掌握并发编程的核心概念。

    07 深入Thread类—线程API精讲.pdf

    需要注意的是,`sleep`方法可能会抛出`InterruptedException`,如果在休眠期间线程被中断,会立即结束休眠并抛出异常。 - `Thread.sleep(long millis)`:参数单位为毫秒,表示线程将睡眠的最短时间。 - `Thread....

Global site tag (gtag.js) - Google Analytics