Restoring Interruption flag status in Java - java

Good Day!
I have been going through the Java Docs & some online resources on properly handling the InterruptedException due to bug reported by SonarQube. But not sure if I 100% understood if Interruption flag status always has to be restored whenever InterruptedException occurs inside a place where we can't throw exception for Ex: Runnable implementation.
Lets consider below replicated demo example code, where the main method is responsible for initiating some async method.The async method makes the Http GET request and processes(by taking runnable as argument to the addListener method) the response asynchronously.
Note : Now my query is Do I have to restore Interruption status flag at line#35. Why asking this is because,
This is my complete program, and nowhere am interrupting the task-thread which processes the actual GET request's response. But Interruption can happen due to various factors which I understand. But my requirement is very simple to always return back some default response no matter what exception I get, even if it is InterruptedException. So, even without restoring the flag, my intention/requirement gets fulfilled i.e to complete the CompletableFuture with some default response.
And nowhere in my code I am going check for Thread.interrupted() OR Thread.currentThread().isInterrupted() because I don't want to handle this as my requirement already got fulfilled by returning back default response.
After capturing the InterruptedException and completing the Future with some default response, am not processing anything further within this thread(Runnable).
After executing the InterruptedException catch block, next my Main Thread will start executing with the received default response. And my Main Thread OR Parent Thread doesn't want to know OR doesn't care about if InterruptedException ever occurred-or-not. All it cares about is some valid response.
Incase if I still want to restore the Interruption flag status, could
someone please explain why to restore the same, and how can my code go
wrong if I don't restore it?
. Because, as I said in above 4 points my requirement gets fulfilled even without restoring the flag.
Any enlightment/clarification on this topic for the above exact scenario is highly appreciatable.
Thanks in Advance :)

In your program there you probably don't need to handle InterruptedException indeed.
But in a general case swallowing InterruptedException is a bad idea.
The main reason is that Thread.interrupt() (which causes InterruptedException) is the only way to interrupt many blocking operations provided by Java's standard library.
For instance, the proper handling of InterruptedException is typically required when we want to gracefully shutdown our application (i.e. when we want to close files, network connections and other resources before shutdown).
Some information about this can be found in Thread.interrupt() javadocs.
Also I would recommend this SO answer and related chapters in "Java Concurrency In Practice", mentioned there.

Related

How to deal with: Call to 'Thread.sleep()' in a loop, probably busy-waiting

Guys how to deal with such code and warning?
private void listenOnLogForResult() {
String logs = "";
int timeCounter = 1;
while (logs.isEmpty()) {
try {
timeCounter++;
Thread.sleep(2000); // Wait 2 seconds
} catch (InterruptedException e) {
log.error(e.getLocalizedMessage(), e);
}
if (timeCounter < 30) {
logs = checkLogs()
} else {
logs = "Time out";
}
}
}
I need to pause current thread for 2 seconds to wait file to be filled, but my Intelij Rise an issue here.
And also I am getting error from sonar:
SonarLint: Either re-interrupt this method or rethrow the "InterruptedException".
I've tried already with many ExecutorService, but it is always run in seperate thread, and I need to pause current one.
Please help..
The busy-waiting warning
This is a warning coming from intellij that is dubious, in the sense that what you're doing is often just straight up required. In other words, it is detecting a pattern that is overused, but whose usage cannot be reduced to 0. So, likely the right solution is to just tell intellij to shut up about it here.
The problem it is looking at is not that Thread.sleep. That is not the problem. However, intellij's detector of this pattern needs it to find this case, but it is not what it is complaining about, which might be a little hard to wrap your head around.
What IntelliJ is worried about, is that you're wasting cycles continually rechecking log.isEmpty() for no reason. It has a problem with the while aspect of this code, not the sleep. It would prefer to see code where you invoke some sort of logs.poll() method which will just wait until it is actively woken up by the act of new logs appearing.
If this is all running within a single java process, then you can indeed rewrite this entire system (which includes rewrites to whatever log is here, and a complete re-imagining of the checkLogs() method: Instead of going out and checking, whatever is making logs needs to wake up this code instead.
If it's not, it is likely that you need to tell intellij to shut it: What you are doing is unavoidable without a complete systems redesign.
The re-interrupt warning
You have some deplorable exception handling here.
Your exception handling in general
Do not write catch blocks that log something and keep moving. This is really bad error handling: The system's variables and fields are now in an unknown state (you just caught and logged some stuff: Surely that means you have no idea what conditions have occurred to cause this line of execution to happen!), and yet code will move right along. It is extremely likely that 'catch exceptions and just keep going' style code results in more exceptions down the line: Generally, code that operates on unknown state is going to crash and burn sooner rather than later.
Then, if that crash-and-burn is dealt with in the same fashion (catch it, log it, keep going), then you get another crash-and-burn. You end up with code that will, upon hitting a problem, print 186 exceptions to the log and they are all utterly irrelevant except the first one. That's bad yuyu.
You're also making it completely impossible for calling code to recover. The point of exceptions is that they need to bubble upwards endlessly: Either the exception is caught by code that actually knows how to deal with the problem (and logging it is not dealing with it!), which you are making impossible, or, the code exception should bubble up all the way to the entry-point handler which is the right place to log the error and abort the entry-point handler.
An entry-point handler is a generic module or application runner; out of the box, the code baked into java.exe itself that ends up invoking your psv main() method is the most obvious 'entry point runner', but there's more: Web frameworks will eventually invoke some code of yours that is supposed to handle a web request: That code of yours is analogous to psv main(): It is the entry-point, and the code in the web framework that invokes it, is the entry-point runner.
Entry-point runners have a good reason to catch (Throwable t), and to spend their catch block primarily logging it, though they should generally log a lot more than just the exception (a web handler should for example log the request details, such as which HTTP params were sent and which path request it was, maybe the headers, etc). Any other code should never do this, though.
If you have no idea what to do and don't want to think about what that exception might mean, the correct 'whatever, just compile already javac' code strategy is to add the exception type to your throws line. If that is not feasible, the right code in the catch block is:
} catch (ExceptionIDoNotWantToThinkAboutRightNow e) {
throw new RuntimeException("Uncaught", e);
}
This will ensure that code will not just merrily continue onwards, operating on unknown state, and will ensure you get complete details in logs, and ensures that calling code can catch and deal with it if it can, and ensures that any custom logging info such as the HTTP request details get a chance to make it to the logs. Win-win-win-win.
This case in particular: What does InterruptedEx mean?
When some code running in that java process invokes yourThread.interrupt(), that is how InterruptedException can happen, and it cannot possibly happen in any other way. If the user hits CTRL+C, or goes into task manager and clicks 'end process', or if your android phone decides it is time for your app to get out as the memory is needed for something else - none of those cases can possibly result in InterruptedExceptions. Your threads just get killed midstep by java (if you want to act on shutdowns, use Runtime.getRuntime().addShutdownHook). The only way is for some code to call .interrupt(), and nothing in the core libs is going to do that. Thus, InterruptedException means whatever you think 'call .interrupt() on this thread' means. It is up to you.
The most common definition is effectively 'I ask you to stop': Just shut down the thread nicely. Generally it is bad to try to shut down threads nicely if you want to exit the entire VM (just invoke System.shutdown - you already need to deal with users hitting CTRL+C, why write shutdown code twice in different ways?) - but sometimes you just want one thread to stop. So, usually the best code to put in a catch (InterruptedException e) block is just return; and nothing else. Don't log anything: The 'interrupt' is intentional: You wrote it. Most likely that is nowhere in your code base and the InterruptedException is moot: It won't ever happen.
In your specific code, what happens if your code decides to stop the logger thread is that the logger thread will log something to the error logs, and will then shortcut its 2 second wait period to immediately check the logs, and then just keeps going. That sounds completely useless.
But, it means whatever you want it to. If you want an ability for e.g. the user to hit a 'force check the logs right now' button, then you can define that interrupting the logging thread just shortcuts the 2 seconds (but then just have an empty catch block with a comment explaining that this is how you designed it, obviously don't log it). If you ALSO want a button to 'stop the logging thread', have an AtomicBoolean that tracks 'running' state: When the 'stop log-refreshes' button is hit, set the AB to 'false' and then interrupt the thread: Then the code you pasted needs to check the AB and return; to close the thread if it is false.
fun sleep(timeMillis: Long) {
val currentTimeMillis = System.currentTimeMillis()
while (true) {
if (System.currentTimeMillis() - currentTimeMillis >= timeMillis) {
break
}
}
}
and use this in your method(It's code by koltin,you should trans to java)

How do I prevent an exception from stopping my program?

I'm using a thread to run a half of an application, and the other half is running by itself. I did this so that the one part fetching the data (because I'm running an infinite loop) would not stop the other part from doing it's job. Now I was wondering: if an exception occurred on one part it would block the some of the other part because they are dependent on each other.
So my question is, how could I prevent an exception from stopping my whole program and make it continue do things?
Try-catch or throw an exception. If neither of those sound familiar, I would look them up.
an example of try-catch
try
{
//your code that may throw exception
}catch(TheException e){
e.printStackTrace(); // or however you handle exceptions
}
good resource for throwing exceptions: https://docs.oracle.com/javase/tutorial/essential/exceptions/throwing.html
Throwing an exception from one thread generally will not impact the runtime of the others. Threads are kind of off in their own little world in that regard.
That said, if two threads are sharing some state (whether directly through the heap or indirectly through a database or something like that) and one thread leaves the application's data in an unstable/corrupted state because it bombed out, that could obviously impact the behavior of the other threads, making them do further "bad stuff." You will want to prevent this whenever possible; best way to do it is to document your exceptions as best you can and to catch and handle them when thrown, and to back your logic with robust unit tests.
You can create a boolean variable maybe called running so that while your while loop is working fine, this variable will be true. Immediately an exception is caught, the variable becomes false. Your main task can then check the variable anytime it wants to use the shared data. If the variable is true, read the data; else, do something else like restarting the thread depending on the type of exception caught.
Remember, in order to make the variable false, you will need to include its update in your catch clause.
There are better and more complex methods out there like the use of ExecutorService.

Do exceptions caught and handled by programming languages count as software interrupts?

From the beginning of https://en.wikipedia.org/wiki/Interrupt, it says that a software interrupt can be caused by an exceptional condition in the processor itself (often called a trap or exception).
In many programming languages (C++, Java, Python,...), there are language supports for catching and handling exceptions defined by default, and also exceptions self-defined. For example, try {...} catch .... Let me called both kinds of exceptions "language-supported exceptions" (because I don't know what is the right terminology).
Do the language-supported exceptions count as software interrupts?
When a language-supported exception happens, does the same thing
happen as for handling a software interrupt? Specifically, does the
cpu save the current process into stacks, and then switch to run the
OS kernel which then calls the exception handler, and after
finishing running the handler, resume running the saved process?
No, java language exception has nothing to do with software interrupts
Java language exception just initiates some exception handling code within same process and thread.
No.
An interrupt causes an interrupt handler to be invoked. Once that handler is complete the original code will continue executing from the place it was at when the interrupt happened.
Exceptions are handled in a catch block. Program flow is directly affected.
From your link:
The processor responds by suspending its current activities, saving its state, and executing a function called an interrupt handler (or an interrupt service routine, ISR) to deal with the event. This interruption is temporary, and, after the interrupt handler finishes, the processor resumes normal activities.
Question 1 No. As per your wiki reference one explanation is
The former is often called a trap or exception and is used for
errors or events occurring during program execution that are
exceptional enough that they cannot be handled within the program
itself.
You are able to handle any Java exception within your program. So that is one difference. A Java exception could be triggered by an exceptional condition within the processor but the exception handler in your program is responding to an event generated within the JVM, not directly responding to a software interrupt. The more conventional way to think of software interrputs is
Software interrupt instructions function similarly to subroutine
calls and are used for a variety of purposes, such as to request
services from low-level system software such as device drivers.
Do a little research about how to invoke BIOS or MS/DOS services using the INT x86 instruction (this generates a software interrupt).
Questionn 2. Not necessarily. The JVM can generate an exception that has nothing to do with an exceptional processor condition. Think null reference.
No. Exceptions don't count as software interrupts, nor do they act as software interrupts.
Specifically, language-supported exceptions don't need to call the operating system; a context switch is generally unnecessary. Instead, throwing an exception makes a call to user-side code which understands how to look for handlers, unwind the call stack, and so forth, for that particular language.
To look at it another way: a general-purpose operating system will not know or care about the language-specific details necessary to handle language-supported exceptions. Software interrupts fall under the category of the operating system's ABI, which does not need to be remotely similar to the internal standards of a given language implementation.

Thread Handling after exception

used thread.sleep when exception occurs in my application
if any thing exception occured in any one of the thread it should wait for some time and have to try again
what i am facing the issue means for 100 request if exception occurs for 50 means that should be wait for some time and after try again if any
exception occurs means it should also wait till success
am feeling this going to affect the performance and system usage.
Please let me know your suggestions. Is it better to create new thread if any exception occurs?
Or Any other way?
Retrying on exception isn't a bad idea, but you should make sure that:
The exception is transient (i.e. you have reasons to believe it may
succeed on retry, like a network error)
You have ways to prevent retrying forever (like "max retry")
You don't overload the system by too frequent retries by e.g. using exponential back-off strategy (or even just a reasonably long wait time)
Exception to rule 2 is possible (sometimes you do want stuff to retry forever).
From the question, I understand that, you are talking about RunTimeExceptions.
1) Firstly I would like to suggest that, you should examine the code areas which may really throw the exceptions at run time i.e processing of files.
2) another thing is that you have to handle this scenarios so that exception cases are reduced. i.e first check file is available then only try to read it, check permissions before writing it etc. In this way frequency of retrying may be reduced.
3) If both above actions fails, means the situation which can never be handled such as services are down etc., you can retry the considering all necessary aspects like - MAX try, MAX time out foe which you are re-trying, leave the attempt after certain amount of try OR time etc.
Hope this helps.

In the multi-thread program like producer/consumer, what's the purpose of Swallowing InterruptedException

Some code simply call
catch (InterruptedException ex) {}, why?
This is usually a sign that the developer didn't know how to handle the Exception and thus just ignored it.
This is the sort of bad behaviour that results in some saying checked exceptions are a failed experiment. IMHO Developers should just learn to handle exceptions.
A better way to handle this exception is to either
pass it to the caller. i.e. don't catch it.
call Thread.currentThread().interrupt() so the interrupt is not lost.
If such an exception should be impossible, wrap it in a throw new AssertionError(ex)
That is used in situations where an exception may occur but the response to the exception is the same as normal continuation from the try block. A common example is calling sleep(). (However, that's actually often a bad example because being interrupted often signals that an operation should be abandoned.)
InterruptedException is what's called a checked exception. When added to a method you want to call, it's a way of signifying that you must account for this situation, namely that the time you need to process the results of the call may be pre-empted by another thread in the system.
Assume for the moment that you have 6-7 statements in a try block, and you assume they will run in a more or less atomic fashion. Among those statements is one that relies on thread-aware behavior. If that call is pre-empted, your subsequent statements won't run, and you'll have to handle the consequences.
People have all sorts of reasons for catching this exception but taking no action. I can't think of many good reasons for doing this, unless I can clearly show that being interrupted doesn't create an undesirable side-effect in my code. Given any example piece of code that shows this behavior, I would guess no catch logic was included because a) the programmer had no plan for dealing with it; b) the programmer merely wanted to step past the check so the code compiles.

Categories