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.
Related
I'd like to check to see if a Thread is Interrupted, from some other Thread, without polling this to check - i.e. some kind of monitor.
Specifically, what I am trying to do is force-kill (Stop) a Thread when it is Interrupted. I will include a code example below of a trivial example of what I have done so far - it works, but polling to check if the Thread is interrupted is sub-optimal and I would like to avoid this.
public class ThreadTest
{
public static void main(final String[] args) throws InterruptedException
{
final Thread outerThread = new Thread()
{
#Override
public void run()
{
// Need to externally monitor the thread to detect and process interrupts (for cancellation)
final Thread thread = Thread.currentThread();
new Thread()
{
#Override
public void run()
{
while (true)
{
try
{
Thread.sleep(500);
}
catch (final InterruptedException e)
{}
if (thread.isInterrupted())
{
// Then kill it
thread.stop();
return;
}
}
}
}.start();
uninterruptibleForever();
}
};
outerThread.start();
// Ensure the thread has time to start up
Thread.sleep(500);
outerThread.interrupt();
// The thread should terminate at this point and not continue.
}
/** Some arbitrary task that runs forever and ignores interrupts */
public static void uninterruptibleForever()
{
while (true)
{
System.out.println(MessageFormat.format("I''m still running at {0}", new Date().toLocaleString()));
}
}
}
I can't recommend strongly enough that you don't use Thread#stop().
It should never have existed, was deprecated very quickly and frankly should have been removed about 20 years ago.
You have no idea what the thread is doing when you stop it and it is very easy to corrupt shared objects and leave external resources (e.g. files) in an invalid state.
Suppose the thread is in the middle of resizing a shared ArrayList<> there's risk the object will be corrupted and your whole program fails intermittently in ways you cannot fix.
Do not use Thread#stop() it is broken and cannot be fixed.
It's a terrible feature of Java that it leads people into invalid techniques regarding threads.
Caveat over - how about just overriding interrupt() in a sub-class?
public void interrupt(){
this.stop();
}
You've decided to sub-class Thread (rather than Runnable) so this will "work". "work" in the sense of what you're doing. Not actually work or anything.
The only valid way to solve this is have the thread you want to terminate co-operate by responding to interrupt() as an instruction to come to a suitable point and then terminate cleanly.
Or you can create another flag indicating the thread should end.
I don't know why you need to monitor the thread externally. But here is a small sample how you could do it if you really need it:
import java.util.LinkedList;
import java.util.List;
public abstract class MonitoredCallable implements Runnable {
private final List<InterruptedHandler> interruptedHandlers = new LinkedList<>();
protected abstract void runInternal() throws Exception;
#Override
public final void run() {
try {
runInternal();
} catch(Exception ex) {
}
for (InterruptedHandler interruptedHandler : interruptedHandlers) {
interruptedHandler.threadInterrupted(this);
}
}
public void addInterruptedHandler(InterruptedHandler interruptedHandler) {
this.interruptedHandlers.add(interruptedHandler);
}
public static interface InterruptedHandler {
void threadInterrupted(Thread t);
}
}
Now just use it like this:
MonitoredThread mt = new MonitoredThread() {
#Override
protected void runInternal() throws Exception {
//dosomething
}
};
mt.addInterruptedHandler(t->t.stop());
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'm learning Java concurrency, and tried an example from Java tutorial, with a little experiment (try to catch the exception).
public class SleepMessages {
public static void main(String args[]) {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
try { // my experiment
for (int i = 0; i < importantInfo.length; i++) {
Thread.sleep(4000);
System.out.println(importantInfo[i]);
}
}
catch (InterruptedException ie) {
System.out.println("caught InterruptedException");
}
}
}
And I tried sending it an interrupt signal outside, by "kill -2 $PID".
I expected that while the processing was sleeping, the signal would cause Thread.sleep() to throw the exception, and then I could catch it, but actually not!
Could anyone explain why?
(I'm wondering maybe it's my way sending the signal (kill -2) is not correct.)
The way to handle SIGINT signals from outside, is to register a shutdown hook in your appliation:
public class Main
{
public static void main(final String[] args) throws InterruptedException
{
Runtime.getRuntime().addShutdownHook(new Thread()
{
#Override
public void run()
{
System.out.println("Shutdown hook called!");
}
});
while (true)
{
Thread.sleep(1000);
}
}
}
Now, when you start your program and kill it with kill -2 <PID> the shutdown hook will be invoked and you can gracefully shutdown.
Catching InterruptedException (what you want to do) is possible when you are interrupting your thread from inside your application using interrupt() as the following very basic example demonstrates:
public class Main
{
public static void main( final String[] args )
{
final Thread t1 = new Thread()
{
#Override
public void run()
{
try
{
while ( true )
{
Thread.sleep( 1000 );
}
}
catch ( final InterruptedException e )
{
System.out.println( "This thread was interrupted!" );
}
}
};
t1.start();
t1.interrupt();
}
}
br
InterruptedException is caught when you call Thread.interrupt() on the thread in question. It has nothing whatsoever to do with the kill program.
I tried the same scenario on my ubuntu machine, and found that when we use kill command to kill a process, then It basically kill a entire process, So this behavior is like System.exit(1), But the interrupted exception is something different, where the interrupted status flag is set to tell the thread that it has been received interrupt from some other thread, one more thing, if some other thread will interrupt this thread by calling interrupt() method on this thread instance then you will get InterruptedException only if current thread was sleeping or waiting state. If the thread is running then calling interrupt() method on it will just set the interrupt flag to true (to check interrupt status flag, you can check via isInterrupted() method on this thread instance), and will not throw InterruptedException.
See below code, here I have used System.exit(1), in a different thread, and you will see that the whole Java process was exited, there is no interrupted exception, because of the reasons explained above.
public static void main(String args[]) {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
try { // my experiment
while(true) {
Thread.sleep(4000);
Thread t = new Thread() {
public void run() {
try {
Thread.sleep(1000);
System.exit(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();
System.out.println(importantInfo[0]);
}
}
catch (InterruptedException ie) {
System.out.println("caught InterruptedException");
}
}
Output of above modified code:
Mares eat oats
Process finished with exit code 1
To get this code to compile, I can either:
Put my call to Thread.sleep() in a try/catch block, or
Have printAll() declare that it can throw an InterruptedException.
Why do I have to do this?
class Test {
public static void main( String[] args ) {
printAll( args );
}
public static void printAll( String[] line ) {
System.out.println( lines[ i ] );
Thread.currentThread().sleep( 1000 ):
}
}
(Sample code from Kathy Sierra's SCJP book.)
I know that the exception which Thread.sleep() throws is a checked exception, so I have to handle it, but in what situation does Thread.sleep() need to throw this exception?
If a method is declared in a way that it can throw checked exceptions (Exceptions that are not subclasses of RuntimeException), the code that calls it must call it in a try-catch block or the caller method must declare to throw it.
Thread.sleep() is declared like this:
public static void sleep(long millis) throws InterruptedException;
It may throw InterruptedException which directly extends java.lang.Exception so you have to catch it or declare to throw it.
And why is Thread.sleep() declared this way? Because if a Thread is sleeping, the thread may be interrupted e.g. with Thread.interrupt() by another thread in which case the sleeping thread (the sleep() method) will throw an instance of this InterruptedException.
Example:
Thread t = new Thread() {
#Override
public void run() {
try {
System.out.println("Sleeping...");
Thread.sleep(10000);
System.out.println("Done sleeping, no interrupt.");
} catch (InterruptedException e) {
System.out.println("I was interrupted!");
e.printStackTrace();
}
}
};
t.start(); // Start another thread: t
t.interrupt(); // Main thread interrupts t, so the Thread.sleep() call
// inside t's run() method will throw an InterruptedException!
Output:
Sleeping...
I was interrupted!
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at Main$1.run(Main.java:13)
One Thread can communicate with and interact with another Thread, and one way that it can do it is by interrupting it: if t is another Thread, you can call t.interrupt() to ask it politely to stop what it's currently doing. This is in particular something you might want to do if t is sleeping: you might want to wake it up. What it does is to cause an InterruptedException in t's Thread.sleep() method, so that it can catch it and respond. Because of this, any time you use Thread.sleep() to make the current thread go to sleep, you have to deal with the possibility of an InterruptedException in case another thread decides to wake it up.
In your case, you've only got one Thread, so you know that there can't be an InterruptedException from elsewhere in your code. But it's a not uncommon thing to want to do in multi-threaded code.
class Demo extends Thread{
public void run() {
for (int i = 0; i <10; i++) {
system.out.println("hello Ziyad");
thread.sleep(1000);
}} }
public class Threddemo{
public static void main(string[] args) throws interruptedexception {
Demo t=new Demo();
Demo t2=new Demo();
t.start();
t2.start();
}}
Suppose We have two Thread t and t2 and t is executing while executing, t2 came and t2 is also start executing but t is not finish yet
there the thread get interrupted and you lose your data.In above example t thread is running and when in spleeping mode, and there t2 came
and start executing suddenly t get up but t2 is running this is chance of interruptedexception and data lose to avoid this we use interruptedexception
How do we implement efficient exception handling when using threads.
I have a main program which creates 3 threads. How do we handle the exceptions for the exceptions thrown during the execution of thread?
Can we use the try/catch block or uncaughtexception. If so, can you please share some samples.
public class MyThreadTest {
public static void main(String[] args) {
Thread newThread = new Thread(new ThreadWithException());
// Add the handler to the thread object
newThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("ERROR! An exception occurred in " + t.getName() + ". Cause: " + e.getMessage());
}
});
newThread.start();
}
}
/**
* This thread throws a custom exception in its run method.
*/
class ThreadWithException implements Runnable {
#Override
public void run() {
throw new RuntimeException("Application Specific Exception!!");
}
}
Either you can use:
Thread#setUncaughtExceptionHandler to specify some code that is run when an exception is thrown (outside of normal program flow), or:
ExecutorService#invokeAll to run all of your blocks, and inspect the returned list for Future#get()'s throwing of ExecutionException. Another option is CompletionService, but this is slightly harder to use for such a simple case.
You can use try / catch block strategy:
Thread t = new Thread() {
#Override
public void run() {
try {
//..thread code
} catch (Exception e) {
}
}
};
It is easy to implement but in case of exception main thread of your application will never know what happened inside of child thread.
Better method would be to spawn threads using ExecutorService (as mentioned by FauxFaux). This will allow you to easily pass information about the error to main thread. Besides that, using ExecutorService allows you to write less code. You won't have to manage threads in your code but leave it for ExecutorService instead.
beacuse , recently, I have write a program with about 3 threads in order to fill a lot data from mysql and mongoDb to ElasticSearch. I share u my code.
I use java.util.concurrent.Executors.
First I have a main class. It calls
public void start() throws Exception {
this.logger.info("Main: Start the worker manually");
schedulerThreadPool = Executors.newScheduledThreadPool(this.maxNumberOfThread);
for (int i = 0; i < this.maxNumberOfThread; i++) {
Worker worker = new Worker();
long delay = i * this.sleepBetweenTaskStart;
schedulerThreadPool.scheduleAtFixedRate(worker, delay, this.minTimeBetweenEachTask, TimeUnit.MILLISECONDS);
}
}
And Worker implements Runnable and get Thread Id by below code.
this.threadId = Thread.currentThread().getId();
And just try catch in each Worker. Everything works normally.
#Override
public void run() {
try {
do...
} catch (Exception e) {
e.printStackTrace();
}
}