jack-y
jack-y

Reputation: 433

Java : Thread.sleep() in a thread : no wait

I have a problem with thread not sleeping.
I can't put here my whole code. so, to reproduce, here is a basic code waiting 5 seconds.

try {
    int millisec = 5000;
    System.out.println(new Date());
    System.out.println("We wait " + millisec + " milliseconds");
    Thread.sleep(millisec);
    System.out.println(new Date());
} catch (Exception e) {
    e.printStackTrace();
}

output :

Thu Aug 22 20:01:42 CEST 2013
We wait 5000 milliseconds
Thu Aug 22 20:01:47 CEST 2013

Everything is OK.
But when I put this code in a thread, no sleep. Example with this code :

try {
    Thread aThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                int millisec = 5000;
                System.out.println(new Date());
                System.out.println("We wait " + millisec + " milliseconds");
                Thread.sleep(millisec);
                System.out.println(new Date());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    aThread.start();
} catch (Exception e) {
    e.printStackTrace();
}

output :

Thu Aug 22 20:07:30 CEST 2013
We wait 5000 milliseconds

...and nothing else, the thread is terminated.
I don't understand why. Please, any ideas ?

EDIT : I use Eclipse and JUnit to test.

Upvotes: 4

Views: 2060

Answers (2)

Alex Suo
Alex Suo

Reputation: 3119

Well I think you didn't call join() in your main thread (if you using the JUnit then the thread calling the test case and creating the thread object).

Upvotes: 1

Gray
Gray

Reputation: 116858

Edit:

The issue turned out to be how JUnit works. It does not know that background threads were spawned so when the test thread completes, it kills the rest of the threads without waiting for them.


Your code properly spits out both date lines when I try it in a small main() class. Here are some possibilities as to why you aren't seeing the output in your application:

  • The thread that is spawning the aThread may be a daemon thread itself. The aThread is therefore daemon because its daemon status is gotten from the spawning thread's status. If the JVM finishes before the 2nd System.out.println(...) the aThread will be killed. If there is a question about it, you should do:

    Thread aThread = new Thread(new Runnable() {
    ...
    // ensure the deamon flag is off _before_ we start the thread
    aThread.setDaemon(false);
    aThread.start();
    
  • Another possibility is that something is actually closing System.out before the 2nd println(...);. Unlikely but possible. Are you using shutdown hooks at all for cleanup?

  • A third possibility is that the output is actually being printed but your IDE or your console is somehow not displaying the output.

  • Another possibility is that the System.out.println(...); threw an IOException. It might be interesting to check the value of System.out.checkError() to see if it is true although I'm not sure how you would then display it.

One thing to try is to create a temporary file instead of printing output. Something like:

new File("/var/tmp/" + System.currentTimeMillis()).createNewFile();

Then you should see 2 files in "/var/tmp" (or wherever a temp directory on your OS is).

You should also try changing System.out to System.err to see if that changes anything. Doubtful but worth a try.

If these don't work as well then something is killing the JVM forcefully so it can't wait for the background threads.

Upvotes: 5

Related Questions