Java Threading confusion - code explanation

agantuk

Skilled
I know this is a nuisance. But I am confused. Can someone explain why an InterruptedException is being thrown here?

Code:
public class BadThreads {

    static String message;

    private static class CorrectorThread extends Thread {

        public void run() {
            try {
                sleep(1000); 
            } catch (InterruptedException e) {}
            //Key statement 1:
            message = "Mares do eat oats."; 
        }
    }

    public static void main(String args[]) throws InterruptedException {
        (new CorrectorThread()).start();
        message = "Mares do not eat oats.";
        Thread.sleep(2000);
        //Key statement 2:
        System.out.println(message);
    }
}

The application should print out "Mares do eat oats."
 
So that other thread can call interrupt() on this thread and your thread cleanly exits.
Whenever a thread is interrupted and the thread is sleeping or waiting, it would end by throwing InterruptedException. You have the chance of cleaning up and exiting the thread. This is safer compared to the old mechanism of stop,suspend, resume mechanism. Any good book should explain this, I am too poor when it comes to explaining stuff. :(
 
^ Yes, I know that when a thread is interrupted during a sleep or wait, it throws an InterruptedException.

However, my question in this case is, what is causing the interrupt in this particular example? If you run the code above, you would notice that it executes the try (sleep), and then immediately goes to the catch block. However, the sleep in the main method wakes up only a second after the InterruptedException is thrown. Which means that the main thread didn't probably cause the exception, right?
 
currently on phone, so cant check what its printing

print something in catch block and see if its really throwing exception

you have a race condition there, you cant change message in two threads without a lock
 
OK, so what I had done earlier was this - this is the same program with lots of sysouts thrown in:

Code:
import java.sql.Timestamp;

public class BadThreads {

    static String message;

    private static class CorrectorThread extends Thread {

        public void run() {
            try {
            	System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : before run sleep");
                sleep(1000); 
                System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : slept in run");
            } catch (InterruptedException e) {}
            //Key statement 1:
            System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : interrupted now");
            message = "Mares do eat oats."; 
        }
    }

    public static void main(String args[]) throws InterruptedException {
        (new CorrectorThread()).start();
        System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : assigning in main");
        message = "Mares do not eat oats.";
        System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : assigned in main");
        Thread.sleep(2000);
        System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : main woke up");
        //Key statement 2:
        System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : " + message);
    }
}

And on execution, it gives output as

Code:
main:2010-07-10 18:12:17.015 : assigning in main
main:2010-07-10 18:12:17.028 : assigned in main
Thread-0:2010-07-10 18:12:17.022 : before run sleep
Thread-0:2010-07-10 18:12:18.028 : slept in run
Thread-0:2010-07-10 18:12:18.028 : interrupted now
main:2010-07-10 18:12:19.028 : main woke up
main:2010-07-10 18:12:19.028 : Mares do eat oats.

If you see there is nothing really happening which should cause the interrupt.
 
import java.sql.Timestamp;

public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : interrupted now");
}
}

Try it this way. If exception is really thrown, you must see the message, otherwise not.
 
Use this program and check that no exception is being thrown.

Code:
import java.sql.Timestamp;

public class GoodThreads {

    static String message;

    private static class CorrectorThread extends Thread {

        public void run() {
            try {
                sleep(1000); 
            } catch (InterruptedException e) {
				System.out.println("exception Caught" + e.getMessage());
			}
            System.out.println("Correcter thread ends");
        }
    }

    public static void main(String args[]) throws InterruptedException {
        (new CorrectorThread()).start();        
        Thread.sleep(2000);        
        System.out.println("main thread ends");
    }
}

You are depending on your message string being printed which is being changed from two threads without proper synchronization which is bound to give undefined results.

agantuk said:
OK, so what I had done earlier was this - this is the same program with lots of sysouts thrown in:

Code:
import java.sql.Timestamp;

public class BadThreads {

    static String message;

    private static class CorrectorThread extends Thread {

        public void run() {
            try {
            	System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : before run sleep");
                sleep(1000); 
                System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : slept in run");
            } catch (InterruptedException e) {}
            //Key statement 1:
            System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : interrupted now");
            message = "Mares do eat oats."; 
        }
    }

    public static void main(String args[]) throws InterruptedException {
        (new CorrectorThread()).start();
        System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : assigning in main");
        message = "Mares do not eat oats.";
        System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : assigned in main");
        Thread.sleep(2000);
        System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : main woke up");
        //Key statement 2:
        System.out.println(Thread.currentThread().getName() + ":" + new Timestamp (System.currentTimeMillis()) + " : " + message);
    }
}

And on execution, it gives output as

Code:
main:2010-07-10 18:12:17.015 : assigning in main
main:2010-07-10 18:12:17.028 : assigned in main
Thread-0:2010-07-10 18:12:17.022 : before run sleep
Thread-0:2010-07-10 18:12:18.028 : slept in run
Thread-0:2010-07-10 18:12:18.028 : interrupted now
main:2010-07-10 18:12:19.028 : main woke up
main:2010-07-10 18:12:19.028 : Mares do eat oats.

If you see there is nothing really happening which should cause the interrupt.
You could see here that it's actually sleeping for ~1 sec(17.022 to 18.028) and you are printing "interrupted now" after the catch block, which is bound to be printed.
 
haraakiri said:
You could see here that it's actually sleeping for ~1 sec(17.022 to 18.028) and you are printing "interrupted now" after the catch block, which is bound to be printed.
Oh boy! That was really stupid of me, not to notice that line. Damn. All this while I was thinking that the sysout and the message assignment were IN the InterruptedException block and not outside. Height of stupidity. So sorry :)

Thanks a lot for taking time on this one, and my apologies. However, really appreciate your help :)
 
Back
Top