Related
I am writing a custom bounded scheduler. This should be able to schedule tasks with a given delay. Try to schedule tasks if the bound has been reached, throwing an exception after a timeout. Here is what I have so far:
public class BoundedScheduledExecutor {
private final ScheduledThreadPoolExecutor executor;
private final Semaphore semaphore;
private final int maxWaitSeconds;
private static final Logger LOG = LoggerFactory.getLogger(
BoundedScheduledExecutor.class
);
// constructor omitted
public ScheduledFuture<?> schedule(Runnable task, long delay, TimeUnit unit)
throws Exception {
try {
boolean result = semaphore.tryAcquire(this.maxWaitSeconds, TimeUnit.SECONDS);
LOG.info("result {}", result);
LOG.info("executor {}", this.executor.getActiveCount());
LOG.info("semaphore {}", this.semaphore);
if (result) {
return this.executor.schedule(
() -> {
try {
LOG.info("before run");
task.run();
} finally {
semaphore.release();
}
},
delay,
unit
);
} else {
semaphore.release();
throw new RejectedExecutionException();
}
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
} catch (InterruptedException e) {
throw e;
}
}
}
The code is based on a similar implementation from Java concurrency in practice. In my test, I am trying to verify that if I have a short task and another task following that, the second one is scheduled once the short task finishes. My test is this:
public void itSchedulesAfterTimeoutWhenQueueIsFull() throws Exception {
this.boundedScheduledExecutor = new BoundedScheduledExecutor(executor, 1, 3);
Runnable blockingTask = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {}
}
};
Runnable simpleTask = new Runnable() {
#Override
public void run() {}
};
this.boundedScheduledExecutor.schedule(blockingTask, 0, TimeUnit.SECONDS);
this.boundedScheduledExecutor.schedule(simpleTask, 5, TimeUnit.SECONDS);
}
But the second call to schedule throws an exception because tryAcquire returns false. I expect my test should succeed because the first task takes 1s and is scheduled right away. The second one is scheduled after 5s, I was expecting the semaphore will be released in between so that the second task can proceed. I noticed that the semaphore is not released in the finally block for the scheduled task. How do I get the semaphore to release after a task is complete? Why doesn't the finally block execute?
return this.executor.schedule(
() -> {
try {
LOG.info("before run");
task.run();
} finally {
semaphore.release();
}
},
delay,
unit
);
This code does not execute the lambda, it just sends it to the executor that will execute it at some time.
Even if the executor starts running the lambda as soon as it receives it, your main code will not wait for it and the return will be applied, even if the lambda is still running the task.
So it may very well be that the first scheduled task still has not been able to release the semaphore before you invoke this method again, unless you are adding additional controls outside of this code.
In fact with your code you cannot have more than one task scheduled at a given time; until the task currently scheduled has not being finished you will not release the semaphor, but you require acquiring it to schedule a new task.
I have Java main class, in the class, I start a new thread, in the main, it waits until the thread dies. At some moment, I throw a runtime exception from the thread, but I can't catch the exception thrown from the thread in the main class.
Here is the code:
public class Test extends Thread
{
public static void main(String[] args) throws InterruptedException
{
Test t = new Test();
try
{
t.start();
t.join();
}
catch(RuntimeException e)
{
System.out.println("** RuntimeException from main");
}
System.out.println("Main stoped");
}
#Override
public void run()
{
try
{
while(true)
{
System.out.println("** Started");
sleep(2000);
throw new RuntimeException("exception from thread");
}
}
catch (RuntimeException e)
{
System.out.println("** RuntimeException from thread");
throw e;
}
catch (InterruptedException e)
{
}
}
}
Anybody knows why?
Use a Thread.UncaughtExceptionHandler.
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread th, Throwable ex) {
System.out.println("Uncaught exception: " + ex);
}
};
Thread t = new Thread() {
#Override
public void run() {
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException();
}
};
t.setUncaughtExceptionHandler(h);
t.start();
That's because exceptions are local to a thread, and your main thread doesn't actually see the run method. I suggest you read more about how threading works, but to quickly summarize: your call to start starts up a different thread, totally unrelated to your main thread. The call to join simply waits for it to be done. An exception that is thrown in a thread and never caught terminates it, which is why join returns on your main thread, but the exception itself is lost.
If you want to be aware of these uncaught exceptions you can try this:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Caught " + e);
}
});
More information about uncaught exception handling can be found here.
This explains the state transition of threads dependening on whether an exceptions occured or not:
Source : http://www-public.imtbs-tsp.eu/~gibson/Teaching/CSC7322/L8-ExceptionsAndThreads.pdf
Most likely;
you don't need to pass the exception from one thread to another.
if you want to handle an exception, just do it in the thread which threw it.
your main thread doesn't need to wait from the background thread in this example, which actually means you don't need a background thread at all.
However, lets assume you do need to handle an exception from a child thread another. I would use an ExecutorService like this:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
System.out.println("** Started");
Thread.sleep(2000);
throw new IllegalStateException("exception from thread");
}
});
try {
future.get(); // raises ExecutionException for any uncaught exception in child
} catch (ExecutionException e) {
System.out.println("** RuntimeException from thread ");
e.getCause().printStackTrace(System.out);
}
executor.shutdown();
System.out.println("** Main stopped");
prints
** Started
** RuntimeException from thread
java.lang.IllegalStateException: exception from thread
at Main$1.call(Main.java:11)
at Main$1.call(Main.java:6)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
** Main stopped
Please take a look at Thread.UncaughtExceptionHandler
Better (alternative) way is to use Callable and Future to get the same result...
Use Callable instead of Thread, then you can call Future#get() which throws any exception that the Callable threw.
AtomicReference is also a solution to pass the error to the main thread .Is same approach like the one of Dan Cruz .
AtomicReference<Throwable> errorReference = new AtomicReference<>();
Thread thread = new Thread() {
public void run() {
throw new RuntimeException("TEST EXCEPTION");
}
};
thread.setUncaughtExceptionHandler((th, ex) -> {
errorReference.set(ex);
});
thread.start();
thread.join();
Throwable newThreadError= errorReference.get();
if (newThreadError!= null) {
throw newThreadError;
}
The only change is that instead of creating a volatile variable you can use AtomicReference which did same thing behind the scenes.
Currently you are catching only RuntimeException, a sub class of Exception. But your application may throw other sub-classes of Exception. Catch generic Exception in addition to RuntimeException
Since many of things have been changed on Threading front, use advanced java API.
Prefer advance java.util.concurrent API for multi-threading like ExecutorService or ThreadPoolExecutor.
You can customize your ThreadPoolExecutor to handle exceptions.
Example from oracle documentation page:
Override
protected void afterExecute(Runnable r,
Throwable t)
Method invoked upon completion of execution of the given Runnable. This method is invoked by the thread that executed the task. If non-null, the Throwable is the uncaught RuntimeException or Error that caused execution to terminate abruptly.
Example code:
class ExtendedExecutor extends ThreadPoolExecutor {
// ...
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null)
System.out.println(t);
}
}
Usage:
ExtendedExecutor service = new ExtendedExecutor();
I have added one constructor on top of above code as:
public ExtendedExecutor() {
super(1,5,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(100));
}
You can change this constructor to suit your requirement on number of threads.
ExtendedExecutor service = new ExtendedExecutor();
service.submit(<your Callable or Runnable implementation>);
Also from Java 8 you can write Dan Cruz answer as:
Thread t = new Thread(()->{
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException(); });
t.setUncaughtExceptionHandler((th, ex)-> log(String.format("Exception in thread %d id: %s", th.getId(), ex)));
t.start();
I faced the same issue ... little work around (only for implementation not anonymous objects ) ... we can declare the class level exception object as null ... then initialize it inside the catch block for run method ... if there was error in run method,this variable wont be null .. we can then have null check for this particular variable and if its not null then there was exception inside the thread execution.
class TestClass implements Runnable{
private Exception ex;
#Override
public void run() {
try{
//business code
}catch(Exception e){
ex=e;
}
}
public void checkForException() throws Exception {
if (ex!= null) {
throw ex;
}
}
}
call checkForException() after join()
Did you play around with setDefaultUncaughtExceptionHandler() and the alike methods of the Thread class? From the API: "By setting the default uncaught exception handler, an application can change the way in which uncaught exceptions are handled (such as logging to a specific device, or file) for those threads that would already accept whatever "default" behavior the system provided."
You might find the answer to your problem there... good luck! :-)
If you implement Thread.UncaughtExceptionHandler in class that starts the Threads, you can set and then rethrow the exception:
public final class ThreadStarter implements Thread.UncaughtExceptionHandler{
private volatile Throwable initException;
public void doSomeInit(){
Thread t = new Thread(){
#Override
public void run() {
throw new RuntimeException("UNCAUGHT");
}
};
t.setUncaughtExceptionHandler(this);
t.start();
t.join();
if (initException != null){
throw new RuntimeException(initException);
}
}
#Override
public void uncaughtException(Thread t, Throwable e) {
initException = e;
}
}
Which causes the following output:
Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: UNCAUGHT
at com.gs.gss.ccsp.enrichments.ThreadStarter.doSomeInit(ThreadStarter.java:24)
at com.gs.gss.ccsp.enrichments.ThreadStarter.main(ThreadStarter.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.RuntimeException: UNCAUGHT
at com.gs.gss.ccsp.enrichments.ThreadStarter$1.run(ThreadStarter.java:15)
Exception handling in Thread : By default run() method doesn’t throw any exception, so all checked exceptions inside the run method has to be caught and handled there only and for runtime exceptions we can use UncaughtExceptionHandler. UncaughtExceptionHandler is an interface provided by Java to handle exceptions in a Thread run method. So we can implement this interface and set back our implementing class back to Thread object using setUncaughtExceptionHandler() method. But this handler has to be set before we call start() on the tread.
if we don’t set uncaughtExceptionHandler then the Threads ThreadGroup acts as a handler.
public class FirstThread extends Thread {
int count = 0;
#Override
public void run() {
while (true) {
System.out.println("FirstThread doing something urgent, count : "
+ (count++));
throw new RuntimeException();
}
}
public static void main(String[] args) {
FirstThread t1 = new FirstThread();
t1.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("Exception thrown by %s with id : %d",
t.getName(), t.getId());
System.out.println("\n"+e.getClass());
}
});
t1.start();
}
}
Nice explanation given at http://coder2design.com/thread-creation/#exceptions
It is almost always wrong to extend Thread. I cannot state this strongly enough.
Multithreading Rule #1: Extending Thread is wrong.*
If you implement Runnable instead you will see your expected behaviour.
public class Test implements Runnable {
public static void main(String[] args) {
Test t = new Test();
try {
new Thread(t).start();
} catch (RuntimeException e) {
System.out.println("** RuntimeException from main");
}
System.out.println("Main stoped");
}
#Override
public void run() {
try {
while (true) {
System.out.println("** Started");
Thread.sleep(2000);
throw new RuntimeException("exception from thread");
}
} catch (RuntimeException e) {
System.out.println("** RuntimeException from thread");
throw e;
} catch (InterruptedException e) {
}
}
}
produces;
Main stoped
** Started
** RuntimeException from threadException in thread "Thread-0" java.lang.RuntimeException: exception from thread
at Test.run(Test.java:23)
at java.lang.Thread.run(Thread.java:619)
* unless you want to change the way your application uses threads, which in 99.9% of cases you don't. If you think you are in the 0.1% of cases, please see rule #1.
My solution with RxJava:
#Test(expectedExceptions = TestException.class)
public void testGetNonexistentEntry() throws Exception
{
// using this to work around the limitation where the errors in onError (in subscribe method)
// cannot be thrown out to the main thread
AtomicReference<Exception> ex = new AtomicReference<>();
URI id = getRandomUri();
canonicalMedia.setId(id);
client.get(id.toString())
.subscribe(
m ->
fail("Should not be successful"),
e ->
ex.set(new TestException()));
for(int i = 0; i < 5; ++i)
{
if(ex.get() != null)
throw ex.get();
else
Thread.sleep(1000);
}
Assert.fail("Cannot find the exception to throw.");
}
For those who needs to stop all Threads running and re-run all of them when any one of them is stopped on an Exception:
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// could be any function
getStockHistory();
}
public void getStockHistory() {
// fill a list of symbol to be scrapped
List<String> symbolListNYSE = stockEntityRepository
.findByExchangeShortNameOnlySymbol(ContextRefreshExecutor.NYSE);
storeSymbolList(symbolListNYSE, ContextRefreshExecutor.NYSE);
}
private void storeSymbolList(List<String> symbolList, String exchange) {
int total = symbolList.size();
// I create a list of Thread
List<Thread> listThread = new ArrayList<Thread>();
// For each 1000 element of my scrapping ticker list I create a new Thread
for (int i = 0; i <= total; i += 1000) {
int l = i;
Thread t1 = new Thread() {
public void run() {
// just a service that store in DB my ticker list
storingService.getAndStoreStockPrice(symbolList, l, 1000,
MULTIPLE_STOCK_FILL, exchange);
}
};
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable exception) {
// stop thread if still running
thread.interrupt();
// go over every thread running and stop every one of them
listThread.stream().forEach(tread -> tread.interrupt());
// relaunch all the Thread via the main function
getStockHistory();
}
};
t1.start();
t1.setUncaughtExceptionHandler(h);
listThread.add(t1);
}
}
To sum up :
You have a main function that create multiple thread, each of them has UncaughtExceptionHandler which is trigger by any Exception inside of a thread. You add every Thread to a List. If a UncaughtExceptionHandler is trigger it will loop through the List, stop every Thread and relaunch the main function recreation all the Thread.
You cannot do this, since it doesn't really make sense. If you hadn't called t.join() then you main thread could be anywhere in the code when the t thread throws an exception.
I'm using a FixedThreadPool to run many threads. The methods doJobs() sometimes throws a runtime exception whose stacktrace is printed on the console but is not logged. It means that this exception is not caught in the catch(Throwable) in MyRunnable. The main problem is that after this exception, the Executor will stop executing any threads already submitted, and the whole application will just hang. How is it possible that this exception is not logged? Also, why the whole executor does not continue and does not finish but just hangs with no activity?
class MyRunnable implements Runnable {
public void run() {
try {
doJob();
}
catch(Error e){ log(e);}
catch(Throwable e) {log(e);}
}
}
//main method
final ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
for (final MyRunnable wc : runnables) {
executor.execute(wc);
}
try {
executor.awaitTermination(maxTime, TimeUnit.HOURS);
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
I've code that looks like this:
public static void startService() {
try{
new Thread(new Runnable() {
#Override
public void run() {
throw new RuntimeException("Some exception");
}
}).start();
}catch (Exception e){
//Exception handling
}
}
How can I handle this exception in the catch() block in parrent thread?
UPD: This threads have to work asynchronous
You have several options to handle exceptions thrown by threads. One is to have a general uncaught exceptions handler:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
//log the exception or handle it here if possible
}
});
But it is difficult to link an exception caught that way with a specific thread.
Or you can use an ExecutorService instead of starting the thread manually:
ExecutorService executor = Executors.newCachedThreadPool();
Future<?> future = executor.submit(new Runnable() {
#Override
public void run() {
throw new RuntimeException("Some exception");
}
});
try {
future.get();
} catch (ExecutionException e) {
Throwable yourException = e.getCause(); //here you can access the exception
}
If you mean it is inside of Runnable's run() method then you will have to use another approach. Use Callable instead! Callable call() method allows you to return a value and throw an exception.
Please have a look here for an example on how to use Callable. Also, note that it is better to use a higher level api such as ExecutorService which manages the lifecycle of your threads and provides thread pooling. (included in the example)
you would have to use an Callable.
The thread.run method will never throw an exception since it is - well - executed in a different thread and in this was will not interfere with your calling thread.
if you execute a callable (by e.g. running it via an ExecutorService) you get a Future result which in turn will throw the given exception when calling the future.get() method.
Use throw statement in catch block.
public static void startService() {
try{
new Thread(new Runnable() {
#Override
public void run() {
}
}).start();
}catch (Exception e){
throw e;
}
}
Rethrowing an exception is simply adding throw e in the catch block
I have Java main class, in the class, I start a new thread, in the main, it waits until the thread dies. At some moment, I throw a runtime exception from the thread, but I can't catch the exception thrown from the thread in the main class.
Here is the code:
public class Test extends Thread
{
public static void main(String[] args) throws InterruptedException
{
Test t = new Test();
try
{
t.start();
t.join();
}
catch(RuntimeException e)
{
System.out.println("** RuntimeException from main");
}
System.out.println("Main stoped");
}
#Override
public void run()
{
try
{
while(true)
{
System.out.println("** Started");
sleep(2000);
throw new RuntimeException("exception from thread");
}
}
catch (RuntimeException e)
{
System.out.println("** RuntimeException from thread");
throw e;
}
catch (InterruptedException e)
{
}
}
}
Anybody knows why?
Use a Thread.UncaughtExceptionHandler.
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread th, Throwable ex) {
System.out.println("Uncaught exception: " + ex);
}
};
Thread t = new Thread() {
#Override
public void run() {
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException();
}
};
t.setUncaughtExceptionHandler(h);
t.start();
That's because exceptions are local to a thread, and your main thread doesn't actually see the run method. I suggest you read more about how threading works, but to quickly summarize: your call to start starts up a different thread, totally unrelated to your main thread. The call to join simply waits for it to be done. An exception that is thrown in a thread and never caught terminates it, which is why join returns on your main thread, but the exception itself is lost.
If you want to be aware of these uncaught exceptions you can try this:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Caught " + e);
}
});
More information about uncaught exception handling can be found here.
This explains the state transition of threads dependening on whether an exceptions occured or not:
Source : http://www-public.imtbs-tsp.eu/~gibson/Teaching/CSC7322/L8-ExceptionsAndThreads.pdf
Most likely;
you don't need to pass the exception from one thread to another.
if you want to handle an exception, just do it in the thread which threw it.
your main thread doesn't need to wait from the background thread in this example, which actually means you don't need a background thread at all.
However, lets assume you do need to handle an exception from a child thread another. I would use an ExecutorService like this:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
System.out.println("** Started");
Thread.sleep(2000);
throw new IllegalStateException("exception from thread");
}
});
try {
future.get(); // raises ExecutionException for any uncaught exception in child
} catch (ExecutionException e) {
System.out.println("** RuntimeException from thread ");
e.getCause().printStackTrace(System.out);
}
executor.shutdown();
System.out.println("** Main stopped");
prints
** Started
** RuntimeException from thread
java.lang.IllegalStateException: exception from thread
at Main$1.call(Main.java:11)
at Main$1.call(Main.java:6)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
** Main stopped
Please take a look at Thread.UncaughtExceptionHandler
Better (alternative) way is to use Callable and Future to get the same result...
Use Callable instead of Thread, then you can call Future#get() which throws any exception that the Callable threw.
AtomicReference is also a solution to pass the error to the main thread .Is same approach like the one of Dan Cruz .
AtomicReference<Throwable> errorReference = new AtomicReference<>();
Thread thread = new Thread() {
public void run() {
throw new RuntimeException("TEST EXCEPTION");
}
};
thread.setUncaughtExceptionHandler((th, ex) -> {
errorReference.set(ex);
});
thread.start();
thread.join();
Throwable newThreadError= errorReference.get();
if (newThreadError!= null) {
throw newThreadError;
}
The only change is that instead of creating a volatile variable you can use AtomicReference which did same thing behind the scenes.
Currently you are catching only RuntimeException, a sub class of Exception. But your application may throw other sub-classes of Exception. Catch generic Exception in addition to RuntimeException
Since many of things have been changed on Threading front, use advanced java API.
Prefer advance java.util.concurrent API for multi-threading like ExecutorService or ThreadPoolExecutor.
You can customize your ThreadPoolExecutor to handle exceptions.
Example from oracle documentation page:
Override
protected void afterExecute(Runnable r,
Throwable t)
Method invoked upon completion of execution of the given Runnable. This method is invoked by the thread that executed the task. If non-null, the Throwable is the uncaught RuntimeException or Error that caused execution to terminate abruptly.
Example code:
class ExtendedExecutor extends ThreadPoolExecutor {
// ...
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null)
System.out.println(t);
}
}
Usage:
ExtendedExecutor service = new ExtendedExecutor();
I have added one constructor on top of above code as:
public ExtendedExecutor() {
super(1,5,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(100));
}
You can change this constructor to suit your requirement on number of threads.
ExtendedExecutor service = new ExtendedExecutor();
service.submit(<your Callable or Runnable implementation>);
Also from Java 8 you can write Dan Cruz answer as:
Thread t = new Thread(()->{
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException(); });
t.setUncaughtExceptionHandler((th, ex)-> log(String.format("Exception in thread %d id: %s", th.getId(), ex)));
t.start();
I faced the same issue ... little work around (only for implementation not anonymous objects ) ... we can declare the class level exception object as null ... then initialize it inside the catch block for run method ... if there was error in run method,this variable wont be null .. we can then have null check for this particular variable and if its not null then there was exception inside the thread execution.
class TestClass implements Runnable{
private Exception ex;
#Override
public void run() {
try{
//business code
}catch(Exception e){
ex=e;
}
}
public void checkForException() throws Exception {
if (ex!= null) {
throw ex;
}
}
}
call checkForException() after join()
Did you play around with setDefaultUncaughtExceptionHandler() and the alike methods of the Thread class? From the API: "By setting the default uncaught exception handler, an application can change the way in which uncaught exceptions are handled (such as logging to a specific device, or file) for those threads that would already accept whatever "default" behavior the system provided."
You might find the answer to your problem there... good luck! :-)
If you implement Thread.UncaughtExceptionHandler in class that starts the Threads, you can set and then rethrow the exception:
public final class ThreadStarter implements Thread.UncaughtExceptionHandler{
private volatile Throwable initException;
public void doSomeInit(){
Thread t = new Thread(){
#Override
public void run() {
throw new RuntimeException("UNCAUGHT");
}
};
t.setUncaughtExceptionHandler(this);
t.start();
t.join();
if (initException != null){
throw new RuntimeException(initException);
}
}
#Override
public void uncaughtException(Thread t, Throwable e) {
initException = e;
}
}
Which causes the following output:
Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: UNCAUGHT
at com.gs.gss.ccsp.enrichments.ThreadStarter.doSomeInit(ThreadStarter.java:24)
at com.gs.gss.ccsp.enrichments.ThreadStarter.main(ThreadStarter.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.RuntimeException: UNCAUGHT
at com.gs.gss.ccsp.enrichments.ThreadStarter$1.run(ThreadStarter.java:15)
Exception handling in Thread : By default run() method doesn’t throw any exception, so all checked exceptions inside the run method has to be caught and handled there only and for runtime exceptions we can use UncaughtExceptionHandler. UncaughtExceptionHandler is an interface provided by Java to handle exceptions in a Thread run method. So we can implement this interface and set back our implementing class back to Thread object using setUncaughtExceptionHandler() method. But this handler has to be set before we call start() on the tread.
if we don’t set uncaughtExceptionHandler then the Threads ThreadGroup acts as a handler.
public class FirstThread extends Thread {
int count = 0;
#Override
public void run() {
while (true) {
System.out.println("FirstThread doing something urgent, count : "
+ (count++));
throw new RuntimeException();
}
}
public static void main(String[] args) {
FirstThread t1 = new FirstThread();
t1.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("Exception thrown by %s with id : %d",
t.getName(), t.getId());
System.out.println("\n"+e.getClass());
}
});
t1.start();
}
}
Nice explanation given at http://coder2design.com/thread-creation/#exceptions
It is almost always wrong to extend Thread. I cannot state this strongly enough.
Multithreading Rule #1: Extending Thread is wrong.*
If you implement Runnable instead you will see your expected behaviour.
public class Test implements Runnable {
public static void main(String[] args) {
Test t = new Test();
try {
new Thread(t).start();
} catch (RuntimeException e) {
System.out.println("** RuntimeException from main");
}
System.out.println("Main stoped");
}
#Override
public void run() {
try {
while (true) {
System.out.println("** Started");
Thread.sleep(2000);
throw new RuntimeException("exception from thread");
}
} catch (RuntimeException e) {
System.out.println("** RuntimeException from thread");
throw e;
} catch (InterruptedException e) {
}
}
}
produces;
Main stoped
** Started
** RuntimeException from threadException in thread "Thread-0" java.lang.RuntimeException: exception from thread
at Test.run(Test.java:23)
at java.lang.Thread.run(Thread.java:619)
* unless you want to change the way your application uses threads, which in 99.9% of cases you don't. If you think you are in the 0.1% of cases, please see rule #1.
My solution with RxJava:
#Test(expectedExceptions = TestException.class)
public void testGetNonexistentEntry() throws Exception
{
// using this to work around the limitation where the errors in onError (in subscribe method)
// cannot be thrown out to the main thread
AtomicReference<Exception> ex = new AtomicReference<>();
URI id = getRandomUri();
canonicalMedia.setId(id);
client.get(id.toString())
.subscribe(
m ->
fail("Should not be successful"),
e ->
ex.set(new TestException()));
for(int i = 0; i < 5; ++i)
{
if(ex.get() != null)
throw ex.get();
else
Thread.sleep(1000);
}
Assert.fail("Cannot find the exception to throw.");
}
For those who needs to stop all Threads running and re-run all of them when any one of them is stopped on an Exception:
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// could be any function
getStockHistory();
}
public void getStockHistory() {
// fill a list of symbol to be scrapped
List<String> symbolListNYSE = stockEntityRepository
.findByExchangeShortNameOnlySymbol(ContextRefreshExecutor.NYSE);
storeSymbolList(symbolListNYSE, ContextRefreshExecutor.NYSE);
}
private void storeSymbolList(List<String> symbolList, String exchange) {
int total = symbolList.size();
// I create a list of Thread
List<Thread> listThread = new ArrayList<Thread>();
// For each 1000 element of my scrapping ticker list I create a new Thread
for (int i = 0; i <= total; i += 1000) {
int l = i;
Thread t1 = new Thread() {
public void run() {
// just a service that store in DB my ticker list
storingService.getAndStoreStockPrice(symbolList, l, 1000,
MULTIPLE_STOCK_FILL, exchange);
}
};
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable exception) {
// stop thread if still running
thread.interrupt();
// go over every thread running and stop every one of them
listThread.stream().forEach(tread -> tread.interrupt());
// relaunch all the Thread via the main function
getStockHistory();
}
};
t1.start();
t1.setUncaughtExceptionHandler(h);
listThread.add(t1);
}
}
To sum up :
You have a main function that create multiple thread, each of them has UncaughtExceptionHandler which is trigger by any Exception inside of a thread. You add every Thread to a List. If a UncaughtExceptionHandler is trigger it will loop through the List, stop every Thread and relaunch the main function recreation all the Thread.
You cannot do this, since it doesn't really make sense. If you hadn't called t.join() then you main thread could be anywhere in the code when the t thread throws an exception.