NetBeans / Java / New hint: Thread.sleep called in loop

我与影子孤独终老i 提交于 2019-11-27 01:00:31

问题


In NetBeans, there's a new hint that says: Thread.sleep called in loop.

Question 1: How/when can it be a problem to sleep in a loop?

Question 2: If it's a problem, what should I do instead?

UPDATE: Question 3: Here's some code. Tell me in this case if I should be using something else instead of Thread.Sleep in a loop. In short, this is used by a server which listens for client TCP connections. The sleep is used here in case the max number of sessions with clients is reached. In this situation, I want the application to wait until a free session becomes available.

public class SessionManager {
    private static final int DEFAULT_PORT = 7500;
    private static final int SLEEP_TIME = 200;
    private final DatabaseManager database = new DatabaseManager();
    private final ServerSocket serverSocket = new ServerSocket(DEFAULT_PORT);

public SessionManager() throws IOException, SQLException
{
}

public void listen()
{
while (true)
    if (Session.getSessionCount() < Session.getMaxSessionCount())
        try
        {
             new Thread(new Session(database, serverSocket.accept())).start();
        }
        catch (IOException ex) { ex.printStackTrace(); }
    else
        try
        {
            Thread.sleep(SLEEP_TIME);
        }
        catch (InterruptedException ex) { ex.printStackTrace(); }
}

public static void main(String[] args) throws IOException, SQLException
{
new SessionManager().listen();
}
}

回答1:


Calling sleep in a loop typically leads to poor performance. For example:

while (true) {
    if (stream.available() > 0) {
       // read input
    }
    sleep(MILLISECONDS);
}

If MILLISECONDS is too large, then this code will take a long time to realize that input is available.

If MILLISECONDS is too small, then this code will waste a lot of system resources check for input that hasn't arrived yet.

Other uses of sleep in a loop are typically questionable as well. There's usually a better way.

If it's a problem, what should I do instead?

Post the code and maybe we can give you a sensible answer.

EDIT

IMO, a better way to solve the problem is to use a ThreadPoolExecutor.

Something like this:

public void listen() {
    BlockingQueue queue = new SynchronousQueue();
    ThreadPoolExecutor executor = new ThreadPoolExecutor(
            1, Session.getMaxSessionCount(), 100, TimeUnit.SECONDS, queue);
    while (true) {
        try {
            queue.submit(new Session(database, serverSocket.accept()));
        } catch (IOException ex) { 
            ex.printStackTrace();
        }
    }
}

This configures the executor to match the way your code currently works. There are a number of other ways you could do it; see the javadoc link above.




回答2:


As others have said it depends on the usage. A legitimate use would be a program that is designed to do something every 10 seconds (but is not so critical that exact timing is needed). We have lots of these "utility apps" that import data and other such tasks every few minutes. This is an easy way to perform these tasks and we typically will set the sleep interval to be very low and use a counter so that the program stays responsive and can exit easily.

int count = 0;
while (true) {

    try {
        // Wait for 1 second.
        Thread.sleep(1000);
    }
    catch (InterruptedException ex) {}

    // Check to see if the program should exit due to other conditions.
    if (shouldExit())
        break;

    // Is 10 seconds up yet? If not, just loop back around.
    count++;
    if (count < 10) continue;

    // 10 seconds is up. Reset the counter and do something important.
    count = 0;
    this.doSomething();
}



回答3:


I think I come across one completely legitimate use of sleep() method in loop.

We have one-way connection between server and client. So when client wants to achieve asynchronous communication with server, he sends message to the server and than periodically polls for some response from server. There needs to be some Timeout interval.

Response resp = null;
for (int i = 0; i < POLL_REPEAT && resp == null; i++) {
    try {
       Thread.sleep(POLL_INTERVAL);
    } catch (InterruptedException ie) {
    }
    resp = server.getResponse(workflowId);
}

POLL_REPEAT * POLL_INTERVAL ~ TIMEOUT interval




回答4:


How/when can it be a problem to sleep in a loop?
People sometimes employ it in place of proper synchronization methods (like wait/notify).

If it's a problem, what should I do instead?
Depends on what you're doing. Although it's dificult for me to imagine situation where doing this is the best approach, I guess that's possible too.

You can check Sun's concurrency tutorial on this subject.



来源:https://stackoverflow.com/questions/3535754/netbeans-java-new-hint-thread-sleep-called-in-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!