How to handle InterruptedException?
在线程编程中往往会遇到这个异常,但是我们该怎么处理这个异常呢?今天搜了Google,摘下来:
http://www.artima.com/forums/flat.jsp?forum=276&thread=161312
In his
latest DeveloperWorks article, Brian Goetz discusses strategies for
dealing with InterruptedException. The article shows how swallowing
InterruptedException can lead to unpredictable application behavior,
and outlines strategies for cancellable tasks as a way to manage this
aspect of Java concurrency.
Most developers deal with InterruptedException
by simply swallowing it. Brian Goetz in his recent DeveloperWorks article
shows why this is wrong:
The worst thing you can do with InterruptedException
is swallow it—catch it and neither rethrow it nor reassert the thread's
interrupted status. The standard approach to dealing with an exception
you didn't plan for—catch it and log it—also counts as swallowing the
interruption because code higher up on the call stack won't be able to
find out about it. (Logging InterruptedException
is also just silly because by the time a human reads the log, it is too late to do anything about it.)
The article explains the notion of a blocking method:
When a method throws InterruptedException
... it is telling you that it is a blocking method and that it will
make an attempt to unblock and return early—if you ask nicely... The
completion of a blocking method ... is ... dependent on some external
event, such as timer expiration, I/O completion, or the action of
another thread (releasing a lock, setting a flag, or placing a task on
a work queue). Ordinary methods complete as soon as their work can be
done, but blocking methods are less predictable because they depend on
external events. Blocking methods can compromise responsiveness because
it can be hard to predict when they will complete.
A method that calls a blocking method becomes a blocking method as well. The main benefit of InterruptedException
is the ability to deal with blocking methods by allowing cancellation
of such methods from another thread and then letting the interrupted
thread perform cleanup work.
For
instance, in a GUI application, the user might be given a chance to
interrupt a blocking method, or in a server application a monitoring
component can cancel a task given some operational conditions, such as
a timeout. When a caller interrupts a blocking method, the blocking
method will have an opportunity to perform cleanup work by handling InterruptedException
.
If no special cleanup is required, the article suggests that the blocking method should handle InterruptedException
by re-interrupting the current thread:
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();
}
}
The main reason for doing is that the interruption request that resulted in InterruptedException
may have multiple recipients:
The standard thread pool (ThreadPoolExecutor
)
worker thread implementation is responsive to interruption, so
interrupting a task running in a thread pool may have the effect of
both canceling the task and notifying the execution thread that the
thread pool is shutting down. If the task were to swallow the interrupt
request, the worker thread might not learn that an interrupt was
requested, which could delay the application or service shutdown.
What
do you think of the article's conclusions? What are your strategies for
handling blocking methods, and how do you deal with InterruptedException
in your code?
http://203.208.37.132/search?q=cache:ZfdrN3gjDEoJ:michaelscharf.blogspot.com/2006/09/dont-swallow-interruptedexception-call.html+How+to+handle+InterruptedException&cd=6&hl=zh-CN&ct=clnk&gl=cn&st_usg=ALhdy28Tiz_OPdS_v5AmbeiF2ZRExDzpSQ
Have you ever written the following code?
try {
doSomething();
} catch(InterruptedException
swallowed) {
// BAD BAD PRACTICE, TO IGNORE THIS EXCEPTION
// just logging is also not a useful option here....
}
I have! I newer knew what the heck to do with those annoying
InterruptedException
when I simply wanted to call Thread.sleep(..). What is this
InterruptedException
? Why is it thrown? Why can't I ignore it?
Before I explain the whys, here is what you should do (if you don't re-throw):
try {
doSomething();
} catch(InterruptedException
e) {
// Restore the interrupted status
Thread.currentThread().interrupt()
;
}
What is the InterruptedException
?
There is no way to simply stop a running thread in java (
don't even consider using
the deprecated method
stop()
). Stopping threads is cooperative in java. Calling
Thread.interrupt()
is a way to tell the thread to stop what it is doing. If the thread is in a blocking call, the blocking call will throw an
InterruptedException
,
otherwise the interrupted flag of the tread will be set. A Thread or a
Runnable that is interruptable should check from time to time
Thread.currentThread().isInterrupted()
. If it returns true, cleanup and return.
Why is it InterruptedException
thrown?
The problem is that blocking calls like
sleep()
and
wait()
, can take very long till the check can be done. Therefore they throw an
InterruptedException
. However the isInterrupted is cleared when the
InterruptedException
is thrown! (I have some vague idea why this is the case, but for whatever reason this is done, that is how it is!)
Why can't InterruptedException
be simply ignored?
It should be clear by now: because
ignoring an InterruptedException
means resetting the interrupted status of the thread
.
For example, worker threads take runnable from a queue and execute they
may check the interrupted status periodically. If you swallow it the
thread would not know that it was interrupted and would happily
continue to run.
Some more thoughts
Unfortunately
it is not specified that Thread.interrupt() can only be used for
cancellation. It can be used for anything that requires to set a flag
on a thread. So, ending your task or runnable early might be the wrong
choice, if the interrupted status is used for something else. But
common practice is to use it for cancellation. But even if it is used
for something else, you code does not have the right to reset the
interrupt flag (unless you are the owner of the thread).
To learn more read the nice article
Dealing with InterruptedException
by Brian Goetz.
Or read
Java Concurrency in Practice
By BriaBrian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, and Doug Lea. It's a great book!
If you program in java 5 this book is a must read!
.
I bought the book after I read Brians artikle. I have not yet read the
entire book, but what I have read impresses me. It gives a lot of
theorie and options. Very competent and complete, but I'm missing a set
of simple patterns for concurrent programming. I'm looking forward to
Doug Leas 3rd edition of
Concurrent Programming in Java
Summary:
If you don't know what to do with an InterruptedException
call Thread.currentThread().interrupt()
11
comments:
Firstly, .interrupt() does not mean 'quit'. It means, well,
interrupt. It's a way of notifying that your thread needs to do
something, be it start again, cancel, quit, reiterate, reload config
file ... it's basically the same as kill -HUP, which is interpreted in
a number of different ways depending on the program.
Secondly,
why catch it at all? Propagate the exception upwards. That's good
practice for pretty much any exception that you don't know what to do
with.
Wow - get a clue dude. That is the exactly wrong advice of what to do regarding InterruptedException
!!!
Here's the correct answer:
1) DON'T call Thread.currentThread().interrupt()!!! Your thread was already interrupted, which was why you received the InterruptedException
in the first place. Why one earth would you want to interrupt it
again?!?!? Not to mention that you're telling the thread that was
already interrupted to then go and interrupt itself!!!! Duh!
2)
If you've coded your thread loops properly with a termination condition
(e.g., while (!finished)) then doing nothing when you receive an InterruptedException
is a perfectly reasonable thing to do. You told a thread to block on
some operation until some condition was met (e.g., it was given some
data). However, someone else wants to interrupt the operation before
that condition was met. (Most likely a thread shut-down process of some
sort.) So your thread gets woken up without its required condition
being met. So what? Check whether the thread is supposed to terminate
or keep running. If it should terminate (i.e., it's being shut down)
then let it exit the thread loop and die. If not, then let it loop
again and go back to blocking.
Sheesh! Have some clue what you're talking about before you write something like this in public.
Alex, I agree, re-trow is the best solution. But there are cases,
when you cannot propagate the interrupted exception. In these cases it
would get swallowed if you don't re-throw and you don't call interrupt.
But if you don't know what the meaning of the -HUP signal is, you should better not swallow it.
Michael
Anonymous, good that you are anonymous, because you should maybe
read the documentation before you blame me of not understanding what I
am talking about.
1) In the documentation of
Thread.sleep(long) (as in any other method that throws
InterruptedExceptin) it says: "The interrupted status of the current
thread is cleared when this exception is thrown".
2) I agree,
that it is not reliable to use interrupt to terminate your operation.
However, the interrupt flag might mean something to someone outside
your scope. By catching the exception and not restoring the interrupted
state you are swallowing important information.....
Sheesh! Have some clue what you're talking about before you write something like this in public. ;-)
There is another solution to handle
InterruptedException
when you cannot throw it. It's possible to wrap the InterruptedException
into a RuntimeExcpetion. This might help in cases where you don't want to interrupt the whole thread.
I think Anonymous is at least partly right. The interrupted status
doesn't seem like very reliable information exactly because how many
complex scenarios there are that can clear it. For example, one query
method also clears it:
"public static boolean interrupted()
Tests whether the current thread has been interrupted. The interrupted status of the thread is cleared by this method. ..."
I
think it's better to use a custom property for any meaningful thread
statuses. Of course, this usually means some kind of common base class
or interface for threads, which is also not a great solution.
Villane,
it's true that the Thread.interrupt() is not really
reliable, because its not well defined how to use it. But it is the
*only* way to terminate a blocking call..
Michael
Hello,
I find this discussion very useful. I have coded a
garbage collector which runs in a separate thread and removes objects
from a cache. The code is as follows:
public void run(){
while (true){
try{
Thread.sleep(SOME_DURATION);
cache.lock.writeLock().lock();
//clean up the cache
cache.lock.writeLock().unlock();
}
catch(InterruptedException
ie){
}
}//while
}
I
think I am okay with not adding the Thread.currentThread().interrupt()
in the catch block because I don't want the garbage collector to be
turned off during program execution. I wonder though if the thread
could ever be interrupted by some process that has been asked to
terminate the thread...for example a program from which you can
gracefully shut down a running application. You would not know the
source of the InterruptedException
.
If the code above was interrupted by a program which wants to shut down
the thread, then the while loop should be terminated. If some action in
the loop caused the interrupt, then the loop should continue, and be
given a chance to repeat the action at a later time.
If possible, please let me know the possible sources which would invoke the interrupt and if my concerns are valid.
Thanks so much.
-Paula
Paula,
if you create the thread and you have control over the
thread, then you can swallow the exception. You have somehow to define
your own mechanism to shut down the thread. If you want to stop the
Thread, while it is sleeping for SOME_DURATION, you'd have to call the
method Thread.interrupt(). But if you swallow the interrupt you won't
get out of your infinite while loop. If you use the interrupt state of
your thread as mechanism to shut it down your loop would look like:
while(!isInterrupted()) {
try {
Thread.sleep(SOME_DURATION);
//clean up the cache
} catch(InterruptedException
ie){
break;
}
}
But
then you should make sure that no code that you call from within the
loop is swallowing the interrupt exception. And that is really the
problem. Because there is so much code out there that swallows InterruptedException
, using the thread interrupt mechanism is not really reliable....
Michael
hello every body.
I would like to know how i could stop my threads with a boolean .
public class myThread implements Runnable{
private Thread T1;
public void Start ( ) {
myThread = new Thread( this );
myThread.start();
}
public void run(){
try{
for (int i=0; i<
someThing; i++){
traitement();
Thread.sleep(1000);
}//end for
catch(InterruptedException
e){}
}//end try
}//end run
// and this my method to stop threads but i can't stop it. NEED HELP.
boolean finish = true;
synchronise public void stopThread(){
finish = true;
while(finish){
if (T1.isAlive()){
T1.interrupt();
T1 = null;
}
}
}
}
分享到:
相关推荐
在Java编程语言中,`InterruptedException`是一个非常重要的异常类型,主要与线程的中断机制相关。这个异常通常在以下情况抛出:当一个线程正在阻塞(例如等待I/O或者在`synchronized`块中)并且其他线程通过调用`...
处理 InterruptedException 在 Java 语言中,有很多方法可以抛出 InterruptedException,例如 Thread.sleep() 和 Object.wait()。这些方法都是阻塞方法,它们的完成取决于外部事件,而不是简单地运行完成任务。...
在Java编程中,`InterruptedException`是一个特殊的异常类型,主要用于处理线程中断的情况。当你在代码中调用诸如`Thread.sleep()`, `Thread.join()`, 或 `Object.wait()`等阻塞方法时,如果线程被中断,这些方法会...
`Thread`类是Java多线程编程的核心,而`InterruptedException`异常则是与线程中断密切相关的。本文将深入探讨`InterruptedException`异常,以及如何在实际编程中正确处理它。 首先,我们需要了解线程的中断机制。...
在Java编程语言中,`InterruptedException`是一个非常关键的异常,主要与线程的中断机制相关。这个异常通常在处理线程中断时抛出,当一个线程正在执行时被中断,如果该线程正在阻塞(例如等待I/O或者在`wait()`, `...
### Handle与线程问题 在Android开发中,`Handler`机制是解决子线程与UI主线程通信的关键技术之一。由于Android系统为了确保用户界面的响应性和流畅性,强制所有与用户界面相关的操作都必须在主线程(也称为UI线程...
项目中碰到的,已解决,写个文档记录一下
The experiment aims to implement a data processing task using MAPREDUCE, specifically, to process a log file containing user login records from a social media website. 问题描述 The experiment is ...
在上述示例中,`Thread.sleep(100)`会阻塞当前线程,如果线程在此期间被中断,`sleep()`方法会抛出`InterruptedException`。然而,`InterruptedException`被捕获后,线程的中断状态会被自动清除,除非再次调用`...
The title “java 一手画方一手画圆 多线程” translates to "Java: Drawing Squares and Circles with Multi-Threading." This indicates that the program is designed to draw shapes using two separate threads...
catch (InterruptedException e) { } // Ignore interruptions } } /** Start animating when the browser starts the applet */ public void start() { animator = new Thread(this); // Create a ...
public static void main String args[] throws InterruptedException { MainFrame mainFrame; try { mainFrame new MainFrame ; mainFrame loadGame ; } catch Exception e { e printStackTrace ; } }...
public static void main String args[] throws InterruptedException { MainFrame mainFrame; try { mainFram e new MainFrame ; mainFrame loadGame ; } catch Exception e { e printStackTrace ; } } }...
} catch (IOException | InterruptedException e) { e.printStackTrace(); } } } ``` 在上面的代码中,我们使用`Runtime.getRuntime().exec()`方法执行FFmpeg命令行。`"-i"`参数指定输入文件,而输出文件路径...
- **Thread Interruption:** The `wait()` method can throw an `InterruptedException` if the thread is interrupted while waiting. However, the scenario does not involve interruption, so this exception is...
} catch (InterruptedException e) { e.printStackTrace(); } // 创建并发送消息,消息的what字段作为进度值 Message msg = new Message(); msg.what = i; handler.sendMessage(msg); } // 耗时操作完成...
3. **捕获并处理InterruptedException**:对于那些会抛出`InterruptedException`的方法,我们通常需要在`try-catch`块中捕获它。捕获后,可以清除中断标志(因为这些方法会自动清除),然后根据需要处理中断情况,...