Given this code:
public class TwoThreads {
static Thread laurel, hardy;
public static void main(String[] args) {
laurel = new Thread() {
public void run() {
System.out.println("A");
try {
hardy.sleep(1000);
} catch (Exception e) {
System.out.println("B");
}
System.out.println("C");
}
};
hardy = new Thread() {
public void run() {
System.out.println("D");
try {
laurel.wait();
} catch (Exception e) {
System.out.println("E");
}
System.out.println("F");
}
};
laurel.start();
hardy.start();
}
}
The output includes:
A C D E and F
I'm puzzled about why F is included, given that an IllegalMonitorStateException is thrown when wait() is called outside of synchronized code. Why is the print statement of F reached? I believe that the thread stack blows then, but then the program should pass control to its main stack.
Is this correct?
You are catching the exception in the block that prints "E" effectively swallowing it. The code will then continue on to print "F". Blocks that simply catch exceptions and do nothing else are dangerous for this reason.
you catch the exception so control goes to the catch block then continues executing the code after the try/catch.
In the code above as long as their are non application fatal errors after "D" is printed, "F" will always be printed as all catchable errors are handled.
If there are no thread hangs, this behaviour will be consistent.
Add a boolean check to "F" which is suppressed if there is an error thrown and that will give you the desired behaviour.
As a side note, you're calling Thread's static sleep method on objects, which does something other than you might expect. You shouldn't call static class methods on instances for this reason.
(As for why F is printed, the other guys are correct)
I wonder how you know IllegalMonitorStateException is being thrown. You are consuming any Exception and not doing something like e.printStackTrace();.
Related
I am learning about exception handling and now I have a question.
I think the result of this code is 345,however,I don't know why the result is 35.
Shouldn't it run the code System.out.println(4) even though there is an exception happened?
public class Six {
public static void main(String[] args) {
try {
method1();
} catch(Exception e) {
System.out.println(5);
}
}
static void method1() {
try {
method2();
System.out.println(1);
} catch(ArithmeticException e) {
System.out.println(2);
} finally {
System.out.println(3);
}
System.out.println(4);
}
static void method2() {
throw new NullPointerException();
}
}
In method2() a NullPointerException is thrown whereas in method1() you only catch ArithmethicException which is a different Exception. In this case the the catch block of method1() is not processed. Only the finally block will be executed and then the method exits and the exception is re-thrown to the calling method (main())
No, 4 is not printed because the NullPointerException is still active, it was not caught at that point. The finally block (where 3 is printed) is guaranteed to be executed so you can do cleanup there, but it does not 'stop' the exception.
Is there any difference between following two methods?
Which one is preferable and why?
Prg1:
public static boolean test() throws Exception {
try {
doSomething();
return true;
} catch (Exception e) {
throw new Exception("No!");
}
}
Prg2:
public static boolean test() throws Exception {
try {
doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
return true;
}
Consider these cases where you're not returning a constant expression:
Case 1:
public static Val test() throws Exception {
try {
return doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
// Unreachable code goes here
}
Case 2:
public static Val test() throws Exception {
Val toReturn = null;
try {
toReturn = doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
return toReturn;
}
I would prefer the first one. The second is more verbose and might cause some confusion when debugging.
If test() incorrectly returns null, and you see toReturn being initialized to null, you might think the problem is in test() (especially when test() is not just a simple example like this).
Even though it can only return null if doSomething returns null. But that might be hard to see at a glance.
You could then argue that, for consistency's sake, it's better to always use the first form.
Nope there is no difference between both the methods.
It will return true value in both the cases effectively by resuming the flow of the program as soon an and exception is handled.
Catch will be accessed only when an exception occurs.
I'm assuming this is a general question. Otherwise I might comment on other aspects of your method(s).
I think in the case or small methods like these it doesn't really matter. The method is short enough to understand immediately what's going on, what's related to what etc.
However, in the case of longer methods the flow is much easier to follow in the first example. In my opinion. It keeps together related code and related scenarios. When you're reading the method, the normal execution flow is not broken by the catch block, making it more obvious and "fluent".
public static boolean test() throws Exception {
try {
doSomething();
return true;
} catch (Exception e) {
throw new Exception("No!");
}
}
But I won't generalize this for all methods; it's all about the context.
There is no difference, but the first Prg1 is faster than the Prg2.
I wrote a small class that blocks in a method if the value is null. For some reason, it is throwing a StackOverflowError, what I am doing wrong?
public class BlockingObjectProperty<T> extends SimpleObjectProperty<T> {
public T get() {
if (super.get() == null) {
addListener(((observableValue, t, t1) -> {
synchronized (this) {
notifyAll();
}
}));
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
return super.get();
}
}
Here is my test code:
BlockingObjectProperty<String> blockingObjectProperty = new BlockingObjectProperty<String>();
new Thread(){
public void run(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
blockingObjectProperty.set("hello world");
}
}.start();
System.out.println(blockingObjectProperty.get());
And here is a snippet of the exception:
Exception in thread "main" java.lang.StackOverflowError
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:144)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:69)
at javafx.beans.property.ObjectPropertyBase.addListener(ObjectPropertyBase.java:87)
at com.neonorb.commons.property.BlockingObjectProperty.get(BlockingObjectProperty.java:8)
at javafx.beans.binding.ObjectExpression.getValue(ObjectExpression.java:50)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:152)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:144)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:69)
at javafx.beans.property.ObjectPropertyBase.addListener(ObjectPropertyBase.java:87)
at com.neonorb.commons.property.BlockingObjectProperty.get(BlockingObjectProperty.java:8)
at javafx.beans.binding.ObjectExpression.getValue(ObjectExpression.java:50)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:152)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:144)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:69)
at javafx.beans.property.ObjectPropertyBase.addListener(ObjectPropertyBase.java:87)
at com.neonorb.commons.property.BlockingObjectProperty.get(BlockingObjectProperty.java:8)
When you call addListener JavaFX asks the property for its current value (in ExpressionHelper.java:152), calling getValue() again. Then - since the value is still null - you add another listener and so on ad infinitum.
If you want to wait for some variable to become non-null:
private final Object myVarLock = new Object();
private MyType myVar;
MyType get_myVar() {
synchronized(myVarLock) {
while (myVar == NULL) {
myVarLock.wait();
}
return myVar;
}
}
And to set the variable:
void set_myVar(myType newValue) {
synchronized(myVarLock) {
myVar = newValue;
myVarLock.notifyAll();
}
}
NOTES
The getter waits in a loop. This is necessary for strict correctness because the Java Langauge Spec allows wait() to return even when it has not been notified. (a.k.a., spurious wakeup).
Even if spurious wakeups don't happen in your JVM or in your application, it still is smart to always use a loop. The loop is essential in any algorithm where multiple consumer threads compete with one another to receive events. The loop doesn't cost any more than an if, so you might as well just be in the habit of always using the loop.
The test of myVar and the assignment of myVar both are inside the synchronized blocks. This is important. If they weren't both synchronized then here is what could happen:
Thread A enters the getter, tests myVar and finds that it equals NULL.
Thread B enters the setter, sets myVar non-null, calls myVarLock.notifyAll(), returns. The notification is lost because no other thread was waiting for it.
Thread A calls myVarLock.wait() and waits forever, for an event that is never going to happen again.
In the Code written below although i have not caught the ArithmeticException,yet the exception is handled automatically and with finally Block, the content of main() method is successfully Executed. Whereas if i remove the return statement from finally and make demo as returning void then the program after executing finally block throws MainThread Exception..why is it so?
public class FinallyDemo {
int demo() {
try {
int a=5/0;
}
finally {
System.out.println("Finally Executed");
return 10;
}
}
public static void main(String s[]) {
int a=new FinallyDemo().demo();
System.out.println("Exception Handled");
}
}
Because you return from the finally block, the exception is silently disposed. You should never return from a finally block! (Well, almost always never).
From the Java Language Specification:
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
This also means if you threw a different exception, like an IllegalStateException, from the finally block, the original exception would also be discarded.
public class Test2 {
public static void main(String args[]) {
System.out.println(method());
}
public static int method() {
try {
throw new Exception();
return 1;
} catch (Exception e) {
return 2;
} finally {
return 3;
}
}
}
in this problem try block has return statement and throws exception also...
its output is COMPILER ERROR....
we know that finally block overrides the return or exception statement in try/catch block...
but this problem has both in try block...
why the output is error ?
Because your return statement is unreachable - the execution flow can never reach that line.
If the throw statement was in an if-clause, then the return would be potentially reachable and the error would be gone. But in this case it doesn't make sense to have return there.
Another important note - avoid returning from the finally clause. Eclipse compiler, for example, shows a warning about a return statement in the finally clause.
The compiler exception come from, like my Eclipse dude says
Unreachable code Test2.java line 11 Java Problem
The return statement of your main code block will never be reached, as an exception is thrown before.
Alos notice the return statement of your finally block is, at least, a design flaw, like Eclipse once again says
finally block does not complete normally Test2.javajava line 14 Java Problem
Indeed, as a finally block is only here to provide some clean closing, it is not expected to return something that would override the result normally returned by the method.
The throw new Exception() will be called no matter what, so anything within the try block that follows the throw is Unreachable Code. Hence the Error.
public class Test2 {
public static void main(String args[]) {
System.out.println(method());
}
public static int method() {
try {
throw new Exception();
return 1; //<<< This is unreachable
} catch (Exception e) {
return 2;
} finally {
return 3;
}
}
}
It should eventually return 3.
Because 'return' keyword within try block is unreachable, that's why you are getting compile-time error. Omit that 'return' keyword from try block, and then run your program, your will successfully compile.