简体   繁体   中英

How to avoid use of Thread.Sleep

I never gave the use of Thread.Sleep much thought, until I downloaded the latest version of Netbeans. Netbeans now warns you not to use Thread.Sleep. So I did some research on the topic and found people stating that you only need to use Thread.Sleep for debugging/testing purposes and that if you use it at any other time you have poorly written code.

So my question is how can I keep from using Thread.Sleep in the following situation.

I have written a server application that interfaces with another application. The server has two threads:

  1. Handles the data coming over the socket and sends back other information or just plain acknoledgements.

  2. This is the main thread. After kicking off the socket thread it going into an indefinite while loop. Within this while loop I check to make sure the socket thread is still active and that the user hasn't asked to exit the application via a TrayIcon interface. Then I sleep and continue this while loop.

With this application, the TrayIcon is the only UI.

Here is the snippet I'm referencing:

// continues running as long as the exitth file is not present and 
// the tray icon is not in a safe to exit status.

while(doNotExit())
{

    if (getPrimaryThread() == null || !getPrimaryThread().isAlive())
        resetsThreadAndSocket();

    try
    {
        // check to see if the socket threads are still active, if not create new ones.
        if ((getPrimaryThread() == null || !getPrimaryThread().isAlive()))       
            createSocketThread();

        // check right before sleeping that the user does not want to exit.
        if(getTrayIcon().isExiting())
            break;

        // puts the main Thread to sleep for 3 seconds
           Thread.sleep(3000);
    }
    catch(SQLException ex)
    {
        _log.error(ex.getMessage(), ex);
        restartDatabase();
    }
}

The 'preferred' method in most cases would be to use the ScheduledExecutorService built into JavaSE for performing a periodic task, rather than reimplementing it yourself every time using a while loop and Thread.Sleep() .

There's nothing wrong per-se with your example. The language just now has a much more robust support for doing that built into it as of Java 5.

Instead of your Thread.sleep(3000) do:

getPrimaryThread().join(3000)

This will wait for the thread to exit for 3 seconds.

You should consider attaching an event listener to your tray icon instead of polling its state. That way you won't need an extra thread just for monitoring.

If you can't do that for some reason, you can still do away with the extra thread as the Timer class can do the waiting for you.

You seem to be paranoid that some condition (maybe a RuntimeException or Error?) is going to cause your socket Thread to just die. Ideally, you would design your Socket Thread such that it protected itself from crashing. The following example creates a loop that can only be broken as a result of a JVM Error or Thread interrupt:

public void run() {
    while(!Thread.currentThread.isInterrupted()) {
        try {
            //you application logic
        } catch (RuntimeException e) {
           //log uncaught exception
        }
    }
}

In order to shutdown the application, you would attach a listener to the TrayIcon which contained a reference to the SocketThread and could stop it by simply interrupting it.

socketThread.interrupt();

I'll leave figuring how to add an ActionListener to a TrayIcon up to you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM