Related
I've been using the Java 8 Streams for a while. I came across a situation where I need to stream through a List and pass each element to a method of a class that is not static.
List<String> emps = new ArrayList<>();
emps.add("ABC");
emps.add("DEF");
emps.add("GHI");
I want to call the "start" method of EmpDataGenerator.
EmpDataGenerator generator = new EmpDataGenerator(
Executors.newFixedThreadPool(emps.size()));
I have tried this, but it's not working
emps.stream().map(e-> generator.start(e));
public class EmpDataGenerator {
// Used to signal a graceful shutdown
private volatile boolean stop = false;
private final ExecutorService executor;
public EmpDataGenerator(ExecutorService executor) {
this.executor = executor;
}
public void start(String name ) {
Runnable generator = () -> {
try {
while (!stop) {
//do some processing
}
System.out.println("Broke while loop, stop " + stop);
} catch (Exception e) {
System.out.println("EmpDataGenerator thread caught an exception and halted!");
throw e;
}
};
executor.execute(generator);
}
public void stop() {
stop = true;
// The shutdown the executor (after waiting a bit to be nice)
try {
executor.awaitTermination(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// Purposely ignore any InterruptedException
Thread.currentThread().interrupt();
}
executor.shutdownNow();
}
}
A map must take an input and transform it to something. The start method is void.
There is no need for streams here. A simple forEach should do.
emps.forEach(e-> generator.start(e));
or
emps.forEach(generator::start);
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 am having the same issue from this question
Thread hangs when executing a method via reflection
What they haven't noticed is that the problem is on the .invoke method.
When I comment the line .invoke method on the next snippet, the Callables return the desired "Future" values.
This is my Callable implementation:
public class ParallelCallable implements Callable<Boolean> {
private Class _class;
private Method _method;
public ParallelCallable(ParallelPair pair) {
this._class = pair.getClassType();
this._method = pair.getMethod();
}
public Boolean call() {
Boolean done;
try {
this._method.invoke(null, this._class.newInstance()); // All threads hangs on this line.
done = true;
} catch(Exception ex) {
ex.printStackTrace();
done = false;
}
return done;
}
}
And the next code is where I submit the callables to the ExecutorService:
List<Callable<Boolean>> tasks = new ArrayList<Callable<Boolean>>();
ExecutorService pool = Executors.newFixedThreadPool(10);
try {
futures = pool.invokeAll(this.tasks);
pool.shutdown();
// Wait until all threads are finish
while (!pool.isTerminated()) {
}
boolean isLoaded;
for (Future<Boolean> future : futures) {
isLoaded = future.get();
}
} catch (Exception ex) {
ex.printStackTrace();
}
"this.tasks" is the list of ParallelCallable objects.
All the Threads hangs on the line "this._method.invoke(...)". The methods I invoke are public static and also, there is no exception thrown at all.
Thank you and I hope you can help me!
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.
Is there a standard nice way to call a blocking method with a timeout in Java? I want to be able to do:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
if that makes sense.
Thanks.
You could use an Executor:
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
return something.blockingMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
future.cancel(true); // may or may not desire this
}
If the future.get doesn't return in 5 seconds, it throws a TimeoutException. The timeout can be configured in seconds, minutes, milliseconds or any unit available as a constant in TimeUnit.
See the JavaDoc for more detail.
You could wrap the call in a FutureTask and use the timeout version of get().
See http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
See also Guava's TimeLimiter which uses an Executor behind the scenes.
It's really great that people try to implement this in so many ways. But the truth is, there is NO way.
Most developers would try to put the blocking call in a different thread and have a future or some timer. BUT there is no way in Java to stop a thread externally, let alone a few very specific cases like the Thread.sleep() and Lock.lockInterruptibly() methods that explicitly handle thread interruption.
So really you have only 3 generic options:
Put your blocking call on a new thread and if the time expires you just move on, leaving that thread hanging. In that case you should make sure the thread is set to be a Daemon thread. This way the thread will not stop your application from terminating.
Use non blocking Java APIs. So for network for example, use NIO2 and use the non blocking methods. For reading from the console use Scanner.hasNext() before blocking etc.
If your blocking call is not an IO, but your logic, then you can repeatedly check for Thread.isInterrupted() to check if it was interrupted externally, and have another thread call thread.interrupt() on the blocking thread
This course about concurrency https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
really walks through those fundamentals if you really want to understand how it works in Java. It actually talks about those specific limitations and scenarios, and how to go about them in one of the lectures.
I personally try to program without using blocking calls as much as possible. There are toolkits like Vert.x for example that make it really easy and performant to do IO and no IO operations asynchronously and in a non blocking way.
I hope it helps
There is also an AspectJ solution for that with jcabi-aspects library.
#Timeable(limit = 30, unit = TimeUnit.MINUTES)
public Soup cookSoup() {
// Cook soup, but for no more than 30 minutes (throw and exception if it takes any longer
}
It can't get more succinct, but you have to depend on AspectJ and introduce it in your build lifecycle, of course.
There is an article explaining it further: Limit Java Method Execution Time
I'm giving you here the complete code. In place of the method I'm calling, you can use your method:
public class NewTimeout {
public String simpleMethod() {
return "simple method";
}
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException {
Thread.sleep(1100);
return new NewTimeout().simpleMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(1, TimeUnit.SECONDS);
System.out.println(result);
} catch (TimeoutException ex) {
System.out.println("Timeout............Timeout...........");
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
executor.shutdown(); // may or may not desire this
}
}
}
Thread thread = new Thread(new Runnable() {
public void run() {
something.blockingMethod();
}
});
thread.start();
thread.join(2000);
if (thread.isAlive()) {
thread.stop();
}
Note, that stop is deprecated, better alternative is to set some volatile boolean flag, inside blockingMethod() check it and exit, like this:
import org.junit.*;
import java.util.*;
import junit.framework.TestCase;
public class ThreadTest extends TestCase {
static class Something implements Runnable {
private volatile boolean stopRequested;
private final int steps;
private final long waitPerStep;
public Something(int steps, long waitPerStep) {
this.steps = steps;
this.waitPerStep = waitPerStep;
}
#Override
public void run() {
blockingMethod();
}
public void blockingMethod() {
try {
for (int i = 0; i < steps && !stopRequested; i++) {
doALittleBit();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void doALittleBit() throws InterruptedException {
Thread.sleep(waitPerStep);
}
public void setStopRequested(boolean stopRequested) {
this.stopRequested = stopRequested;
}
}
#Test
public void test() throws InterruptedException {
final Something somethingRunnable = new Something(5, 1000);
Thread thread = new Thread(somethingRunnable);
thread.start();
thread.join(2000);
if (thread.isAlive()) {
somethingRunnable.setStopRequested(true);
thread.join(2000);
assertFalse(thread.isAlive());
} else {
fail("Exptected to be alive (5 * 1000 > 2000)");
}
}
}
You need a circuit breaker implementation like the one present in the failsafe project on GitHub.
Try this. More simple solution. Guarantees that if block didn't execute within the time limit. the process will terminate and throws an exception.
public class TimeoutBlock {
private final long timeoutMilliSeconds;
private long timeoutInteval=100;
public TimeoutBlock(long timeoutMilliSeconds){
this.timeoutMilliSeconds=timeoutMilliSeconds;
}
public void addBlock(Runnable runnable) throws Throwable{
long collectIntervals=0;
Thread timeoutWorker=new Thread(runnable);
timeoutWorker.start();
do{
if(collectIntervals>=this.timeoutMilliSeconds){
timeoutWorker.stop();
throw new Exception("<<<<<<<<<<****>>>>>>>>>>> Timeout Block Execution Time Exceeded In "+timeoutMilliSeconds+" Milli Seconds. Thread Block Terminated.");
}
collectIntervals+=timeoutInteval;
Thread.sleep(timeoutInteval);
}while(timeoutWorker.isAlive());
System.out.println("<<<<<<<<<<####>>>>>>>>>>> Timeout Block Executed Within "+collectIntervals+" Milli Seconds.");
}
/**
* #return the timeoutInteval
*/
public long getTimeoutInteval() {
return timeoutInteval;
}
/**
* #param timeoutInteval the timeoutInteval to set
*/
public void setTimeoutInteval(long timeoutInteval) {
this.timeoutInteval = timeoutInteval;
}
}
example :
try {
TimeoutBlock timeoutBlock = new TimeoutBlock(10 * 60 * 1000);//set timeout in milliseconds
Runnable block=new Runnable() {
#Override
public void run() {
//TO DO write block of code
}
};
timeoutBlock.addBlock(block);// execute the runnable block
} catch (Throwable e) {
//catch the exception here . Which is block didn't execute within the time limit
}
In special case of a blocking queue:
Generic java.util.concurrent.SynchronousQueue has a poll method with timeout parameter.
Assume blockingMethod just sleep for some millis:
public void blockingMethod(Object input) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
My solution is to use wait() and synchronized like this:
public void blockingMethod(final Object input, long millis) {
final Object lock = new Object();
new Thread(new Runnable() {
#Override
public void run() {
blockingMethod(input);
synchronized (lock) {
lock.notify();
}
}
}).start();
synchronized (lock) {
try {
// Wait for specific millis and release the lock.
// If blockingMethod is done during waiting time, it will wake
// me up and give me the lock, and I will finish directly.
// Otherwise, when the waiting time is over and the
// blockingMethod is still
// running, I will reacquire the lock and finish.
lock.wait(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So u can replace
something.blockingMethod(input)
to
something.blockingMethod(input, 2000)
Hope it helps.