There is a worker class which is executing the task. The code snippet is as follows:
public class Worker{
executor.execute( new Runnable() {
public void run() {
LOG.info("Task starting to execute");
try {
Thread.sleep(7000)`
}catch (InterruptedException)
LOG.info("Thread Interrupted");
}
LOG.info("Task Executed");
}
}
}
Here when i stop worker class when it is in sleep mode, as per my knowledge Interrupted Exception should be thrown. But in reality, it's not. Instead it just stops. Can someone please clarify my misconception. I have seen lots of threads related to this question, still my doubt is not clear
Related
I notice, in this javadoc, https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.UncaughtExceptionHandler.html
that an UncaughtExceptionHandler is used for when an exception occurs but is not caught. But, will that thread fail quietly? I guess so, because it is going about its business asynchronously, but I'm investigating a related issue with one of our processes, and am surprised at only being aware of this now, 10+ years into my career.
The thread will fail quietly :)
More than a decade ago a ran into a similar problem. The performance of a system started to degrade over time. Eventually, I identified the cause: an exception was thrown in a worker thread in some custom thread pool and the worker thread was terminated. So over time, the number of live threads in the thread pool started to decrease and performance dropped.
The problem was hidden by the fact that there was no logging of the exception.
[edit]
My answer above is not correct. This is demonstrated in the below example:
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(){
public void run(){
throw new RuntimeException();
}
};
t.start();
TimeUnit.SECONDS.sleep(10);
System.out.println("done");
}
}
When the code is run, the following output is shown:
Exception in thread "Thread-0" java.lang.RuntimeException
at Main$1.run(Main.java:8)
done
So the exception is Logged.
Based on #pveentjar's updated answer I ran the following code:
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
public void run() {
throw new RuntimeException("purposeful!");
}
};
t.setUncaughtExceptionHandler((thread, throwable) -> System.out.println("uncaught: " + throwable.getMessage()));
t.start();
TimeUnit.SECONDS.sleep(10);
System.out.println("done");
}
}
, and ascertained that the uncaughtExceptionHandler seems to catch an exception from the thread that uses it, allowing the developer to do what they want with it, but that leaves the question, why bother with that handler, if not to save a system from a silent failure?
output:
uncaught: purposeful!
[a pause of approximately ten seconds]
done
I finally got to the bottom of my specific problem. It was due to shoddy error handling, allowing the thread to fail quietly:
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
public void run() {
try {
//do some stuff
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("done-worker thead");
throw new RuntimeException("purposeful!");
}
};
t.setUncaughtExceptionHandler(
(thread, throwable) -> System.out.println("main thread; uncaugh exception from worker threadt: " + throwable.getMessage()));
t.start();
TimeUnit.SECONDS.sleep(10);
System.out.println("done-main thead");
}
}
In doing "some stuff", the application hit an OutOfMemoryError, which is not, strictly seaking, an Exception. Changing the above to catch(Throwable t), solved it.
I'm attempting to start another thread that branches from the main thread when thread.start() is called. But it appears to take the main thread in to the thread class. Here is minimum reproducible code of my issue. Thanks for looking.
public class Main {
public static void main(String[] args) throws InterruptedException {
ThreadWhileLoop threadWhileLoop = new ThreadWhileLoop();
//threadWhileLoop.run();
threadWhileLoop.start();
while (true){
Thread.sleep(1000);
System.out.println("Main Thread is doing its thing");
}
}
}
and here is the extended thread class
public class ThreadWhileLoop extends Thread {
#Override
public synchronized void start() {
super.start();
while (true){
System.out.println("ThreadWhileLoopIsRunning");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void run() {
super.run();
while (true){
System.out.println("ThreadWhileLoopIsRunning");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Expected output:
ThreadWhileLoopIsRunning
Main Thread is doing its thing
ThreadWhileLoopIsRunning
Main Thread is doing its thing
ThreadWhileLoopIsRunning
Main Thread is doing its thing
Actual output:
ThreadWhileLoopIsRunning
ThreadWhileLoopIsRunning
ThreadWhileLoopIsRunning
Don’t override start. The start method is used by the calling thread to get the new thread into a runnable state. There are very few good reasons to override it. In your posted code the whole program is running in the main thread.
What you need to do is override the run method in the new thread. Then have the main thread call start, which will cause the run method to execute in a separate thread.
(It would be better to create a Runnable than to override Thread. You can pass the Runnable into the Thread as a constructor argument. With this approach there is less temptation to tamper with the Thread object.)
You can check what thread is running with
System.out.println(Thread.currentThread().getName());
In another answer I have an example of starting a thread using a Runnable: https://stackoverflow.com/a/5915306/217324
I have a thread which runs a task of file parsing. Its set as a daemon thread which runs in background from tomcat startup to shutdown doing its task.
I am looking to handle thread termination upon interruption and server shutdown. I want to know if am going about correctly.
class LoadingModule{ // Thread is started from here
threadsStartMethod() {
Thread t = new Thread(FileParseTask);
t.setDaemon(true);
t.start();
}
}
Class FileParseTask implements Runnable {
#Override
public void run() {
try {
while(!Thread.currentThread.isInterrupted) {
// poll for file creation
// parse and store
}
} catch(Exception exit) {
log.error(message);
Thread.currentThread.interrupt();
}
}
}
would this cleanly exit the thread in all scenarios?
it would depend on the code inside the loop. If the code inside the loop captures the interrupted exception and recovers, you will never see it. Also generic exception "exit" hides other exceptions. Change the code so you know what hit you.
I would do the following
Class FileParseTask implements Runnable {
#Override
public void run() {
while(!Thread.currentThread.isInterrupted) {
try {
// poll for file creation
// parse and store
} catch(Exception exit) {
if (InterruptedException)
break;
else{
//
}
log.error(message);
}
}
}
}
This has worked for me with up to 2K threads with no problems
I have a Thread (implements Runnable) from many branch officer call that thread with their branch code. I set up a name of their thread with branch code.
The problems are...
When an exception occurred in running thread - I can't stop that. And when try to make another thread with any name "ExceptionInInitializerError" or "OutOfMemoryError: Java heap space" comes
"OutOfMemoryError: Java heap space" exception comes When 2 or more thread running at a time.
public MyRunnerClass {
//This method called from many branch with their branch Code
public void executeBranchProcess(String branchCode){
Thread t = new Thread(new Exporter(branchCode);
t.setName(branchCode);
t.start();
}
}
Thread Class here
public class Exporter implements Runnable{
private String branchCode;
public Exporter(String branchCode){
this.branchCode = branchCode;
}
#Override
public void run() {
try {
exportCorner();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void exportCorner() throws InterruptedException{
try{
//Some Process
}catch(Exception e){
// I want to close running thread here
// I am using closeThread(this.branchCode), but not working
}
}
static void closeThread(String branchCode) throws InterruptedException {
Thread thread = null;
for (Thread t : Thread.getAllStackTraces().keySet()) {
if (t.getName().equals(branchCode))
thread = t;
}
if (thread != null) {
thread.interrupt();
thread.join();
}
}
}
You face multiple problems here:
You cannot join a thread in itself. Thread.join() waits until the thread dies. But if you call it from the thread you want to stop, it just waits forever.
To stop a thread you simply have to return from its run() method. In your case, just add return in your catch clause instead of calling closeThread().
It seems that you have some memory problems. Either whatever you do in exportCorner() uses alot of memory or you create to many threads at once. As Andy Turner has mentioned in the comments, it might be usefull to use an ExecutorService to handle your Runnables. This may help you managing your threads and ensure a limited thread count.
I probably changed something in my project unintentionally. Now a key thread gets interrupted when it's not supposed to and isInterrupted returns true when the thread should be running.
Because nobody will find the problem for me, I'm asking for help on ways to find it. I need to find:
at best, the location where thread was actually interrupted and output it in console when the program is running
or all places where it is being interrupted in the code and comment them out one by one
Because IDE tools and debugger may play a role in my search I will add that I'm using NetBeans IDE.
You could run it under a special thread that logs the stack when it is interrupted:
// A simple process.
class Process implements Runnable {
#Override
public void run() {
try {
while (true) {
Thread.sleep(1000L);
}
} catch (InterruptedException ex) {
System.out.println("Interrupted");
}
}
}
public void test() throws InterruptedException {
Thread t = new Thread(new Process()) {
#Override
public void interrupt() {
// Log a stack trace when iterrupted.
new Exception("Where the hell did that come from!").printStackTrace(System.out);
// Pass it up the chain.
super.interrupt();
}
};
t.start();
Thread.sleep(2048);
t.interrupt();
t.join();
}