Java Thread: Run method cannot throw checked exception - java

In Java thread, the 'run' method cannot throw a 'checked exception'. I came across this in the Core Java (vol 1) book. Can someone please explain the reasoning behind it?

Can someone please explain the reasoning behind it?
Yes, because any exception you throw in run method will be carefully ignored by JVM. Thus, throwing it there is probably a mistake (unless you have specific exception handler for the thread, see the docs about that). No reason to incite potentially erroneous behaviour.
Or, with an example.
class MyThread extends Thread {
public void run() {
throw new RuntimeException();
}
}
...
new MyThread().start();
// here thread dies silently with no visible effects at all
edit
Why can't the parent thread 'catch' the exception from the spawned 'child' thread?
#chaotic3quilibrium has already noted in his comment why not: because parent thread has likely moved on already.
new MyThread().start(); // launch thread and forget
// 1000 lines of code further...
i = i + 1; // would you like exception from child thread to be propagated here?

What would catch the exception and handle it? Let's assume that the run method could throw a checked exception. Then you could write code like this:
Thread myThread = new Thread(aRunnable);
try{
myThread.start();
}
catch(Exception e){
e.printStackTrace();
}
//do other stuff
BUT once you call myThread.start, the new thread is started in the background and the current thread continues and exits the try-catch and does other stuff. So if myThread did throw an exception later on, you can't catch it!
What you need to do is deal with the exception within the run method and then probably have a way of notifying another object that this thread failed.

Suppose thread A starts up thread B. Then thread B throws an exception. You might think it would be nice for thread A to catch it. But where? By the time thread B thows the exception, who knows what thread A is doing? To take a trivial example, suppose we have this code in thread A:
try
{
threadB=new PurgeAbandonedCarts();
threadB.start();
}
catch (NullPointerException panic)
{
... handle errors purging abandoned carts ...
}
try
{
processNewOrders();
}
catch (NullPointerException panic)
{
... handle problems in new orders ...
}
finally
{
... clean up ...
}
So we start up thread B to purge abandoned carts. Once it gets starte, we move on to processing new orders. Then thread B throws a null pointer exception. Should it be caught by the catch block associated with thread B, or the one associated with processing new orders?
If it goes to the new orders catch, it's likely that any code here has nothing to do with cleaning up problems with thread B. That can't be the right answer.
If you say the one associated with thread B, then that means that during the processing of new orders, control could suddenly be yanked out and sent back to try thread B catch block. But then what happenned to processing new orders? Do we just stop in the middle? Do we not even hit the finally block? And when we're done, do we then just keep executing and fall through to processing new orders again? Do we process orders twice? This can't be the right answer either.
Thus, there is nowhere to go if run throws an exception. The only logical thing to do is to have the run method catch any exceptions thrown itself, and handle them within the new thread.

throws declarations are part of the methods signature. To allow checked exceptions for Runnable#run, one had to declare them on the Runnable interface and had to try/catch everytime we start a thread.
Then again, we usually don't call the run method, we just implement it. We start() a Thread and then, somehow, the run method is called.
But the most obvious reason: When we start threads, we usually don't want to wait until the run method terminates just to catch exceptions like this:
try {
new Worker().start(); // now wait until run has finished
} catch (SomeThreadException oops) {
// handle checked exception
}

The reason is that exception is thrown back to the caller. Caller of run() method is not your code. It is the Thred itself. So even if run() throws exception the program cannot catch it.
You should put thread execution result to some class level variable and then read it from there. Or alternatively use new API: executors and interface Callable that declares method call() that returns future result of the thread execution.

The more obvious solution to the previous answers is that if you throw a checked exception, you are not correctly implementing run() as specified in the runnable interface.
It won't even compile:
run() in TestClass cannot implement run() in java.lang.Runnable;
overridden method does not throw java.lang.Exception

Related

Kafka Streams Shutdown Hook and Unexpected Exception Handling in the same Stream application

I was tasked with tearing down a Dev environment and setting it up again from scrap to verify our CI-CD processes; only problem was that I messed up creating one topic and so the Kafka Streams application exited with an error.
I dug into it and found the issue and corrected it but as I was digging in I ran into another odd little problem.
I implemented a Unexpected Exception handler as so:
streams.setUncaughtExceptionHandler((t, e) -> {
logger.fatal("Caught unhandled Kafka Streams Exception:", e);
// Do some exception handling.
streams.close();
// Maybe do some more exception handling.
// Open a lock that is waiting after streams.start() call
// to let application exit normally
shutdownLatch.countDown();
});
Problem is that if the application threw an exception because of a topic error when the KafkaStreams::close is call the application seems to dead lock in WindowsSelectorImpl::poll after attempting a call to KafkaStreams::waitOnState.
I thought it might be an issue with calling KafkaStreams::close inside the Exception Handler but I found this SO and a comment from Matthias J. Sax that said it should be ok to call KafkaStreams::Close in the exception handler with the caveat of not calling KafkaStreams::close from multiple threads.
The issue is that I want to implement a shutdown hook to kill the steams application gracefully on request, as well as implement the UnexpectedException handler to clean up and terminate gracefully in the event of exceptions.
I came up with the following solution that checks the KafkaStreams state before calling close and it does actually work, but it seems a bit iffy since I could see other cases besides running (perhaps Pending) where we would want to ensure the KafkaStreams::close it called.
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
logger.fatal("Caught Shutdown request");
// Do some shutdown cleanup.
if (streams.state().isRunning())
{
If this hook is called due to the Main exiting after handling
an exception we don't want to call close again. It doesn't
cause any errors but logs that the application was closed
a second time.
streams.close(100L, TimeUnit.MILLISECONDS);
}
// Maybe do a little bit more clean up before system exits.
System.exit(0);
}));
streams.setUncaughtExceptionHandler((t, e) -> {
logger.fatal("Caught unhandled Kafka Streams Exception:", e);
// Do some exception handling.
if (streams.state().isRunning())
{
streams.close(100L, TimeUnit.MILLISECONDS);
}
// Maybe do some more exception handling.
// Open the Gate to let application exit normally
shutdownLatch.countDown();
// Or Optionally call halt to immediately terminate and prevent call to Shutdown hook.
Runtime.getRuntime().halt(0);
});
Any suggestions about why calling the KafkaSteams:close in the exception handler would be causing such troubles or if there is a better way to implement shutdown hook and the exception handler at the same time it would be greatly appreciated?
Calling close() from an exception handler and from shutdown hook is slightly different. close() might deadlock if called from the shutdown hook (cf. https://issues.apache.org/jira/browse/KAFKA-4366) and thus, you should call it with a timeout.
Also, the issue is related with calling System.exit() from within an uncaught exception handler as described in the Jira. In general, calling System.exit() is quite harsh and should be avoided IMHO.
Your solution seems not to be 100% robust, either, because streams.state().isRunning() could result in a race condition.
An alternative to using a timeout might be to only set an AtomicBoolean within both the shutdown hook and the exception handler and use the "main()" thread to call close if the boolean flag is set to true:
private final static AtomicBoolean stopStreams = new AtomicBoolean(false);
public static void main(String[] args) {
// do stuff
KafkaStreams streams = ...
stream.setUncaughtExceptionHandler((t, e) -> {
stopStreams.set(true);
});
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
stopStreams.set(true);
});
while (!stopStreams.get()) {
Thread.sleep(1000);
}
streams.close();
}

Kill or stop a endless/not-returning-value thread in Java

I have a function in Java. It normally returns a value after it completes its task. However, in some conditions it returns nothing. I create a runnable and run this function as a thread. However, because of its not returning a value, it does not finish although it does its task. The process stays alive because it waits a returning value. Is there a way to kill this thread after it is triggered or after a timeout? Stop() or Destroy() did not work. During debug, the thread is seen as alive and I want it to bi deleted/removed
Runnable runnable = new Runnable() {
#Override
public void run() {
int stat = RunMyFunction();
}
};
Thread thread = new Thread(runnable);
thread.start();
Java does not support killing a thread via any method on java.lang.Thread.
stop() and destroy() do look promising at first glance, but they have both been deprecated.
The documentation for destroy states:
This method was originally designed to destroy this thread without any cleanup. However, the method was never implemented. If if were to be implemented, it would be deadlock-prone
and stop:
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
Thus when the documentation says 'deprecated', what it really means is that they are broken and must never be used!?! The Java API designers put a lot of work into backwards compatibility of their APIs, where other languages would have removed these methods Sun decided to keep them as their internal guides (rightly or wrongly) do not permit the removal of a public api method.
So, the question remains. How is one to get a thread to exit from another thread? Sadly one must go out of ones way to poll an exit variable. This can be a custom variable, or it can be a standard flag within java.lang.Thread that is accessible via 'interrupted()'. The advantage of using interrupted() is that other Java APIs such as IO support this flag during otherwise blocking API calls and will exit throwing an InterruptedException. The detection of calling interrupt() is not immediate, as it sets a flag and relies on the Thread to poll the variable at some point in the future.
Oracle offers a tutorial on how to code using interrupt here.
The real problem you have is that RunMyFunction sometimes never terminates. As others have already stated, killing a thread is not intended in Java, so there is no good way to do it. Instead, you should reason about why you call a possibly non-terminating method. This looks like a code smell. Do the following:
If you are the author of RunMyFunction, make sure that it always terminates or it can be interrupted. You can do this by checking Thread.currentThread().isInterrupted() and throwing an InterruptedException when it is. E.g:
void run(){
while(...){ // this loop sometimes runs forever
if(Thread.currentThread().isInterrupted())
throw new InterruptedException(); // Now, we can "kill" this thread here
}
}
Using ExecuterService you can specify a timeout.
ExecutorService executor = Executors.newFixedThreadPool(1);
List<Callable<String>> tasks = new ArrayList<Callable<String>>();
tasks.add(new Callable<String>() {
#Override
public String call() throws Exception {
int stat = RunMyFunction();
return "Execution Finished";
}
});
new Thread(new Runnable() {
#Override
public void run() {
try {
executor.invokeAll(tasks, 10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
invokeAll(...) is a blocking call so i've added inside a new thread.
Solution 1: Timed run: If you want a method to return or throw an exception after a specified amount of time, use the following method to execute the method on a background thread while waiting for it to complete:
public static void timedRun(Runnable r, long timeout, TimeUnit unit)
throws InterruptedException, TimeoutException {
Future<?> task = executor.submit(r);
try {
task.get(timeout, unit);
} catch (ExecutionException e) {
throw launderThrowable(e.getCause());
} finally {
task.cancel(true);
}
}
private static RuntimeException launderThrowable(Throwable t) {
if (t instanceof RuntimeException) return (RuntimeException)t;
else if (t instanceof Error) throw (Error)t;
else throw new IllegalStateException("Not unchecked", t);
}
(Source: Goetz, Brian, Bloch, Joshua, Bowbeer, Joseph, Lea, Doug, Holmes, David and Peierls, Tim. Java Concurrency in Practice. : Addison-Wesley Longman, Amsterdam, 2006. Listing 5.13 and 7.10)
For executor, you can either create a new one using Executor.newSingleThreadExecutor(), or reuse an existing one.
But be warned: Although this method is guaranteed to return or throw an exception after the specified timeout, it cannot guarantee that the runnable will really stop! It interrupts the executing thread, but if the runnable does not react to thread interruption (e.g. by internally checking Thread.interrupted()), it may continue to run in the background - possibly forever - occupying a thread! But at least it does not block.
Solution 2: Timed run with custom threads: If there is any possibility beside thread interruption to cancel your method call, you can still use the approach above, but then you have to use an Executor with custom ThreadFactory that creates a special Thread instance with overridden interrupt method:
Executor executor = Executor.newSingleThreadExecutor(r -> new WsdlThread(r));
public class WsdlThread extends Thread {
public WsdlThread(Runnable r) { super(r); }
public void interrupt() {
try {
// TODO: do something that will interrupt the wsdl call
// e.g. close connection to server, etc.
// example: ((WsdlRunnable)r).getWsdlConnection().close();
} finally {
super.interrupt();
}
}
}
If this isn't possible too, and Thread.stop() doesn't work either, this last solution might work:
Solution 3: Start non-cancellable call in another JVM:
Use Runtime.exec to start another JVM and execute the method call there (See Executing a Java application in a separate process for more info on how to do this). Runtime.exec will return a Process object, which represents the running process.
You can kill it by calling destroy() or destroyForcibly().

how to close a thread which is doing IO operation

I am having a scenario :
I have a thread which is calling a method where i use Default HTTP client to execute a request. for getting the response I open an InputStream and use a Buffred Reader to read the stream.
While(s = buffer.readline .... )
Inside the while loop i keep looking at the response and see for a string " Hello " ...If i get the string i send the response object back ..
The While loop executes till i get the string
The while loop executes till i press the back key ( android )
Now the scenario works for my 1st point. But i face issue in the 2nd point.
When i press back key, i need to stop my thread.
but i am not able to do it. I tried :
thread.destroy
thread.interrupt
thread = null
None of the above works. In fact my thread is always running...
I am not clear if the issue is with Thread or the issue is with the While loop of the stream.
Because i see that the while loop is executing always..
Please help me the best way i can solve this issue...Whether close the thread or close the stream.
Please help me find way to close the stream and close the thread.
thread.destroy() is deprecated. Do not use it.
The safest way to stop an IO bound thread is by interrupting it.
The thread's logic must cooperate by (1) checking for isInterrupted() status and
(2) catching InterruptedException exception.
It is important that both #1 and #2 above will be handled. interrupt()ing a
thread can in some occasions result in exceptions and in others in setting of
status with no exception!
A safe thread implementation goes like this:
class MyThread {
private volatile boolean wasStopped;
public void run() {
try {
while (!Thread.currentThread().isInterrupted() && !wasStopped) {
do_thread_work();
}
} catch (InterruptedException e) {
return; // gracefully stop thread
}
}
public void gracefullyStop() {
wasStopped = true;
this.interrupt();
}
}
To stop the thread call
thread.gracefullyStop();
This pattern will work fine as long as the thread logic function (do_thread_work)
will not internally catch & dismiss InterruptedException. Be aware.
You will see other implementations that rely solely on isInterrupted() check
without the additional wasStopped flag. I think this is a bad practice.
Why?
Because if the interrupt() was raised while the thread was in a waiting mode
i.e. inside functions wait() join() or sleep(), the thread will indeed be woken,
but its interrupted status will be set to false.
Good luck.

What does this try and catch method do?

try
{
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
I understand what the first part is doing. But what is the catch part waiting for? Like what needs to happen to execute this part.
Every piece of code is run by a "thread". You can think of that as a little virtual processor dedicated to running that particular piece of code.
By calling the Thread.sleep() method, you put this thread in the WAITING state for a certain amount of time. While WAITING, the thread cannot do anything, and in particular, it cannot "hear" calls from other threads.
The only way to wake up the thread and having it run its code again, is to sent it an interruption, which is a very strong signal. This is done by calling the interrupt() method of this thread, from another thread.
When waked up, the thread goes to the RUNNING state again, but to signal the developer that it was waked up earlier than expected, it throws an InterruptedException, which is a checked exception. This is why you have to catch it and deal with it.
The sleep method halts execution of the current thread, in your case 5000 milliseconds (5 seconds). This method however throws InterruptedException which has to be caught.
Because the Thread#sleep() method is defined to throw an InterruptedException under some circumstances, the developer should take care of it when this exact exception occurs. This is why the catch block is needed - to hold the logic which handles the InterruptedException
You thread is going to sleep for 5 seconds.
If another thread tries to wake this thread up (Interrupt). It will end up in the exception block and your stacktrace will be printed.
public class InterruptedException
extends Exception
Thrown when a thread is waiting, sleeping, or otherwise occupied, and
the thread is interrupted, either before or during the activity.
Occasionally a method may wish to test whether the current thread has
been interrupted, and if so, to immediately throw this exception.
Best Explanation is Given ╠══ HERE
If InterruptedException throws(Thread interruption may cause this) from try block that will catch by catch block and as you define in the catch block,it will print the Exception stack trace.
If the Thread is interrupted then it will throw the exception and it will be catched in the catch block.
This is relevant to multithreaded applications.When you have reference to an object of a class that either implements Runnable or extends Thread, and inside that object, a Thread.sleep(i) method has been idling the process, you can call reference.interupt() on that reference and it will trigger the InterruptedException. Here's an example:
In the below code, the Scratch class's run method goes to sleep for 60000 ms (or 1 minute) and prints "I've been interrupted" if it receives an InterruptedExection. The way the code is written, it will not receive this exception and will sleep the entire time. But run it a second time with the line //scratch.interrupt(); uncommented and see what happens.
package scratch;
/**
*
* #author bstidham
*/
public class Scratch extends Thread {
public void run() {
System.out.println("Hello from a thread!");
System.out.println("Going to sleep for 1 minute...");
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
System.out.println("I've been interrupted!");
}
System.out.println("Awake now");
}
public static void main(String args[]) {
Scratch scratch = new Scratch();
scratch.start();
//scratch.interrupt();
}
}

Java Monitors -- Catching InterruptedException

I have a java implementation of a monitor using
java.util.concurrent.locks.Lock;
java.util.concurrent.locks.ReentrantLock;
java.util.concurrent.locks.Condition;
The problem that I'm solving is a readers/writers problem. I have one lock lock & two conditions readers and writers.
I've noticed that the Condition.await() function throws InterruptedException. For now, I've just surrounded the method with a try / catch block. However, the catch block is empty.
I'm wondering when this exception is thrown and how I should be dealing with it.
readers.await() is called when there is a writer writing to a file / there are writers waiting to write to a file.
writers.await() is called when there are one or more readers reading from a file OR a writer is currently writing to a file.
In what cases will InterruptedException be thrown, and how should I deal with them?
Interrupting allows to stop some long/blocking tasks in context of a thread. InterruptedException happens only when someone has set "is interrupted" flag for the given thread.
Now regarding await(). When your thread A is waiting on Condition.await(),usually this means it is parked by
LockSupport.park(Object blocker); (-> sun.misc.Unsafe.park(boolean bln, long l) for Hotspot). Something like this:
public void await() throws InterruptedException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
while (still_waiting) {
LockSupport.park(this);
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
}
Now let's assume the user stops the application. The main thread calls A.interrupt() to finish your thread A. interrupt() is implemented in native Thread.interrupt0(). This call set "is interrupted" flag of the thread and unparks the thread A and the thread sees that it is interrupted and throws InterruptedException.
It depends on system requirements how to catch the InterruptedException. If your thread does some work in the loop, you should break the loop to let the thread to be finished. Also, it is good practice to set "is interrupted" flag back for the current thread if you've just catch an InterruptedException:
try {
...
some.await();
}
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
An old but still good article: http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-

Categories

Resources