views:

97

answers:

5

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 passes to its main stack, is this correct?

+6  A: 

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.

Francis Upton
+1 absolutely right, if you want to print to a log while catching exceptions, make sure you re-throw them afterwards with throw; and not throw e; which would throw a new exception.
ajs410
+3  A: 

you catch the exception so control goes to the catch block then continues executing the code after the try/catch.

objects
A: 

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.

GrayWizardx
A: 

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)

Jorn
A: 

I wonder how you know IllegalMonitorStateException is being thrown. You are consuming any Exception and not doing something like e.printStackTrace();.

fastcodejava