I am fairly new to Java threads, Runnable, and the like.
As such, I'm wondering why the following code does not catch an exception?
Runnable r = () -> {
try {
job.print();
} catch (Exception e) {
e.printStackTrace();
}
};
if (job.printDialog()) {
Thread t = new Thread(r);
r.start();
}
Reading Is there a way to make Runnable's run() throw an exception I gather that:
"... if your run() method is really the target of a Thread, there's no point in throwing an exception because it is unobservable; throwing an exception has the same effect as not throwing an exception (none)." (#erickson)
I should check for exceptions inside the Runnable.run() method.
Why is that? Any "simple" explanations on this matter are highly appreciated!
As you have found out already, there's nothing thats captured outside Runnable running state. Language specifications keep on changing. What might have an explanation today may have something else tomorrow. You might find the answer at Why cannot run() of Runnable throw checked Exceptions?, specifically as to why Callable was added to capture the results from Future.
You can answer this question from both, a logical and a programmatical point of view.
Let's start with the logical one:
You can think of a thread as an "independent executor of code" which is totally independent from other executors of code, except shared memory. The Runnable you have to pass on thread initialization "wraps" the code the thread has to execute. As there's no "higher instance" which could catch an exception, throwing exceptions inside those Runnables doesn't make a lot of sense.
Now the programmatical point of view. The following code snippet is similar to how the interface is defined inside the Java SE:
#FunctionalInterface
interface Runnable {
void run();
}
As the function #run() does NOT throw any checked exceptions, you're not allowed to throw checked exceptions inside #run(). Since Runnables have been designed for use in thread initialization only, this makes perfect sense. Callables, however, contain a throws-clause as they're mainly used in Executors which indeed are able to handle exceptions.
Related
I have a class in Java which has main() function. Lets call it A. There is another class B which implements Runnable interface. In main function of class A, I create a thread of class B and that thread will start executing its logic.
Now if lets say because of some error, the thread of class B died. Then would the process A dies along with that ? If not how can we make process A die when thread of class B dies.
Is vice versa possible, like if process A dies, then would thread of class B dies along with it ? and if not how to make it die ?
Your question is on the topic of how to catch a child thread's exception and raise it in the parent thread.
Technically like the other answer, there is no relationship between what broke in the child thread which indeed raises an exception in the parent thread.
public static void main(String[] args){
Thread child = new Thread(){
public void run () {
try {
Object obj = null;
String s = obj.toString(); //this will throw NullPointer
} catch (NullPointerException e) {
throw new RuntimeException("Hoping this reaches the parent! as NPE but it wont", e);
}
}
};
child.start();
}
However to answer your question on how to rather do it. You can employ the use of Future<?> and have a Runnable or Callable do the equivalent and see the values of the Future Result
Here's an example which can call doSomething():
void doSomething(){
Object s = null;
System.out.println("You want to do something here!" + s.toString()); // This will throw NPE
}
And now lets say you want to run this in a separate thread and catch the exception
ExecutorService executor = Executors.newFixedThreadPool(1);
Future result = pool.submit(this::doSomething());
try {
result.get();
}catch (ExcecutionException e){
e.printStackTrace(); //will show null pointer exception
}
Now, your function which ran in a separate thread from the threadPool will throw an execution exception which you can chose to catch at the main/parent thread and do what you please with that failure.
Hoping this will help!
UPDATE:
Why is killing parent thread from child thread bad practise?
It's a really bad idea to terminate any thread from outside that thread. This is because the terminating thread has no idea what the target is doing and whether it is at a "safe" point to terminate. For example you might be in the middle of writing output, or making calculations, or anything. ref.1
There is never really a good candidate on why you should even stop/kill/terminate the entire JVM either. Unless in my ongoing journey of mastering java and core concepts, never have I ever had to deal with a child process killing a parent.
Just to elaborate, specifically, there is infact no concept of "child" thread or "parent" thread. JVM doesn't even keep track of which thread created which thread either.
Its mostly all based on thread groups eg. "groupA" and "groupB" and there is only a "groupA" created "groupB" which JVM knows and keeps track off.
If you really wish to stop the JVM. Just call System.exit ref.2
Consider having a look at this question also
No; there is effectively zero relationship between a thread and the thread that started it. They have no effect on each other whatsoever. Nor do threads have any relationship to processes (which you start with ProcessBuilder or Runtime.exec and have no relationship to threads).
My program is calling the mathematical solver CPLEX multiple times. There is the possibility of setting a time limit for each time CPLEX is being executed from java, which I am using. The problem is that in some rare instances my program gets just stuck inside the .solve() method provided by CPLEX. I don't know where that fault lies, it is definitely not in the mathematical model I am solving, because exporting it and solving it outside of java works. But this is not what my question is about, although of course I'd be thankful for your input on that, too.
My question is: How can I make my program leave the .solve() method immediately no matter what? In the example below I tried to fix this problem. There, the .solve() method is called in the method execute().
public synchronized void executeSafely(int limitSeconds) {
Thread t = new Thread() {
#Override
public void run() {
execute();
}
};
t.start();
try {
Thread.sleep(3000 * limitSeconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.interrupt();
}
This approach does not work because there is no check for interruption inside the .solve() method and I cannot change that method. Replacing .interrupt() with .stop() does not work either since this leads to the suspension of the thread because of exception ThreadDeath.
So is there any other way of immediately terminating the execution of an external program?
If the method call takes more than 10 seconds I want to kill it and move on.
Is multi-threading my only option to solve this problem?
If I go with multi-threading which I'm very new at, my run method would only contain the one method as follows. If myMethod() gets stuck in an infinite loop is there a way to interrupt this thread?
public void run() {
myMethod();
}
Let's assume myMethod() is the following and changing it is not an option.
while(true){
System.out.println("Thinking.");
for (int i = 0; i < 100000; i++) {
//wasting time
}
}
I was going for Mik378's solution, but I don't think this will work as myMethod doesn't throw the InterruptedException exception.
Using threads to achieve this is tricky. There is no portable and safe method to kill a thread without cooperation from said thread. For further details, see How do you kill a thread in Java? and Why are Thread.stop [et al] deprecated?
A more robust approach is to call the method in the context of a separate process, and kill that process.
An even better approach is to understand why things are getting stuck in the first place, and figure out a way to prevent them from getting stuck (or a way to have a timeout and throw an exception etc). Whether that's a realistic possibility in your case, I don't know.
You can start a thread wrapped around your Runnable (named "thread"). Then do
thread.start();
thread.join(10000);
if (thread.isAlive()) {
thread.interrupt();
}
As NPE mentioned, unless you are coding myMethod() yourself or know that it is sensitive to interruptions, there is no guarantee that this will actually kill the thread.
If you are implementing myMethod yourself, then what you need to do is have something like this inside the loop that method runs within the myMethod():
if (Thread.interrupted()) {
break; // or whatever you need to do to end the method quickly
}
I've left out exception handling. Your compiler will tell you what you need to do in that respect.
With two separated threads:
class Job implements Runnable {
public void run(){
try{
myMethod(); // declared within this class or wherever you want
} catch(InterruptedException){
System.out.println("Interrupted now due probably to infinite loop !!");
}
}
public static void main(String[] args) throws InterruptedException {
Job job = new Job();
Thread process = new Thread(job);
process.start();
process.join(10000); //wait here in order to detect wrong loop
if(process.isAlive()){
process.interrupt();
}
}
}
I agree with NPE, your best bet is to use multithreading with a separate process. That seems to be the safest way if you can't debug the method. Other options would be to simply use a timer and throw an exception if the timer exceeds 10 seconds. But that would be kind of unorthodox.
I am using several threads to do some heavy (and error-prone) processing on a large data set. I require all threads to finish execution, regardless of whether they throw an exception or terminate normally (no value is returned), before the program can continue. I am using a CountDownLatch to achieve this, and an ExecutorService to actually run the jobs. I want the worker threads (let's call them JobManager-s for the sake of argument) to notify the latch even if they throw an exception. A JobManager can take anywhere between a second and an hour to complete, and may fail at any time. The idea is to invoke the "finalizer" method of JobManager if an exception is thrown. Now, the ExecutorService likes to catch exceptions or to conceal the true origin of the ones it does not. I have though of a few ways around this, neither of which is satisfactory:
Use ExecutorService#execute(Runnable r) rather than submit(Runnable r). I can do that since I do not care about the return value of the JobManager. I have provided a custom ThreadFactory, which attaches an UncaughtExceptionHandler to each newly created thread. The problem with this approach is that when UncaughtExceptionHandler#uncaughtException(Thread t, Throwable e) is invoked, t's Runnable is of type ThreadPoolExecutor$Worker, and not of type JobManager, which prevents me from invoking the "finalizer" method.
Use a custom ExecutorService and override the afterExecute(Runnable r, Throwable t) method. This suffers from the same problem as 1.
Wrap the whole JobManager#doWork() in a catch statement and use the return value to indicate if an exception was thrown. I can then submit the jobs and use FutureTask#get() to decide if an exception was thrown. I do not like this solution because I feel return codes the wrong tool when you have an elaborate exception mechanism. Moreover, get() will wait (unless interrupted), which means I cannot handle errors in other threads immediately.
Get rid of the CountDownLatch. Store all Futures in a list and repeatedly poke in until I am satisfied with the states. This might work, but feels like a dirty hack.
Any suggestions are greatly appreciated.
As far as I understand, you can use a simple try-finally block:
public class JobManager {
public void doWork() {
try {
...
} finally {
countDownLatch.countDown();
}
}
}
I am writing a simple threading application. Thread is simply a message consumer and process it. However, if the thread somehow got interrupted and the message is not fully processed, I want to put it back to the queue and let other instances get it. So I had to code it like this:
public void run()
{
Map<String, String> data = null;
try
{
while(true)
{
data = q.getData();
System.out.println(this+" Processing data: "+data);
// let others process some data :)
synchronized(this){
sendEmail(data);
data = null;
}
}
}
catch (InterruptedException e)
{
System.out.println(this+" thread is shuting down...");
if(null!=data)
q.add(data);
}
}
Thanks...
EDIT: Thanks for the responses. Everything is very clear now. I understand that even when lines of codes are in a synchronized block, if any of them can throw InterruptedException then it simply means they can be interrupted at that point. The line q.getData() enters this thread to a 'blocked' state (I am using LinkedBlockedQueue inside the q.getData()). At that point, this thread can be interrupted.
A thread will not catch an InterruptedException any time another thread calls interrupt() on it, nor does that method magically stop whatever it's doing. Instead, the method sets a flag that the thread can read using interrupted(). Certain other methods will check for this flag and raise InterruptedException if it's set. For example, Thread.sleep() and many I/O operations which wait for an external resource throw it.
See the Java Thread Interrupts Tutorial for more information.
In addition to David Harkness's answer: you also don't understand meaning of synchronized keyword.
Synchornized is not a kind of "atomic" or "uninterruptable" block.
Synchornized block doesn't provide any guarantees other than that other threads can't enter synchronized block on the same object (this in your case) at the same time (+ some memory consistency guarantees irrelevant in your case).
Therefore usage of synchornized in your case is pointless, since there is no need to protect data from concurrent access of other threads (also, you are synchronizing on this, I don't think other threads would synchronize on the same object).
See also:
Synchronization
Ignoring for the moment that while(true) puts the thread into a CPU loop...
If sendMail does anything that checks for thread interruption it will throw an interrupted exception. So the answer to your question is likely to be a solid yes, the thread can be interrupted within the synchronized block, and you will have to catch the exception and check for that.
That said, InterruptedException is a checked exception, so short of funny buggers being done at a lower level, sendMail should indicate that it can throw InterruptedException.
Yes
Java synchronization means no other thread can access the same lock while a thread has acquired it.
If you don't want any other thread to be able to access a message (or any other object) use synchronized(message) block.