Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread sleep and thread join

if i put a thread to sleep in a loop, netbeans gives me a caution saying Invoking Thread.sleep in loop can cause performance problems. However, if i were to replace the sleep with join, no such caution is given. Both versions compile and work fine tho. My code is below (check the last few lines for "Thread.sleep() vs t.join()").

public class Test{

    //Display a message, preceded by the name of the current thread
    static void threadMessage(String message) {
        String threadName = Thread.currentThread().getName();
        System.out.format("%s: %s%n", threadName, message);
    }

    private static class MessageLoop implements Runnable {
        public void run() {
            String importantInfo[] = {
                "Mares eat oats",
                "Does eat oats",
                "Little lambs eat ivy",
                "A kid will eat ivy too"
            };
            try {
                for (int i = 0; i < importantInfo.length; i++) {
                    //Pause for 4 seconds
                    Thread.sleep(4000);
                    //Print a message
                    threadMessage(importantInfo[i]);
                }
            } catch (InterruptedException e) {
                threadMessage("I wasn't done!");
            }
        }
    }

    public static void main(String args[]) throws InterruptedException {


        //Delay, in milliseconds before we interrupt MessageLoop
        //thread (default one hour).
        long patience = 1000 * 60 * 60;

        //If command line argument present, gives patience in seconds.
        if (args.length > 0) {
            try {
                patience = Long.parseLong(args[0]) * 1000;
            } catch (NumberFormatException e) {
                System.err.println("Argument must be an integer.");
                System.exit(1);
            }

        }

        threadMessage("Starting MessageLoop thread");
        long startTime = System.currentTimeMillis();
        Thread t = new Thread(new MessageLoop());
        t.start();

        threadMessage("Waiting for MessageLoop thread to finish");
        //loop until MessageLoop thread exits
        while (t.isAlive()) {
            threadMessage("Still waiting...");
            //Wait maximum of 1 second for MessageLoop thread to
            //finish.
            /*******LOOK HERE**********************/
            Thread.sleep(1000);//issues caution unlike t.join(1000)
            /**************************************/
            if (((System.currentTimeMillis() - startTime) > patience) &&
                    t.isAlive()) {
                threadMessage("Tired of waiting!");
                t.interrupt();
                //Shouldn't be long now -- wait indefinitely
                t.join();
            }

        }
        threadMessage("Finally!");
    }
}

As i understand it, join waits for the other thread to complete, but in this case, arent both sleep and join doing the same thing? Then why does netbeans throw the caution?

like image 628
Dhruv Gairola Avatar asked Dec 30 '10 10:12

Dhruv Gairola


2 Answers

There is a difference between join() and sleep(). join() will wait until the timeout expires or the thread finishes. sleep() will just wait for the specified amount of time unless interrupted. So it is perfectly possible for join() to return much faster than the specified time.

The reason why Netbeans warns you about sleep() and not about join() is precisely that difference. join() waits for something meaningful while sleep() just sits there doing nothing. If you aren't waiting for something, then why would you want to wait at all? It is rarely meaningful, hence the warning.

like image 186
Sergei Tachenov Avatar answered Oct 16 '22 22:10

Sergei Tachenov


That they can be used to achieve the same thing doesn't mean they are abused in the same way. People often abuse Thread.sleep() when they should really use a lock or something that blocks:

 // Allow others to notify me when there's work to do
 synchronized (lock) {
     try {
         lock.wait(); // Much better than a loop with sleep
     } catch(InterruptedException e) {
         // someone killed me
         return;
     }
 }


 // or use a BlockingQueue or similar
 Job job = queue.get();
 if (job instanceof ExitJob) return;
like image 34
Aaron Digulla Avatar answered Oct 16 '22 22:10

Aaron Digulla