NetBeans / Java /新提示:在循环中调用Thread.sleep
在NetBeans中,有一个新的提示: Thread.sleep在循环中调用。
问题1:如何在一个循环中睡觉?
问题2:如果是问题,我应该怎么做?
更新:问题3:这是一些代码。 在这种情况下告诉我,如果我应该在循环中使用其他的东西而不是Thread.Sleep。 简而言之,这是由侦听客户端TCP连接的服务器使用的。 在达到与客户端的最大会话数的情况下,此处使用睡眠。 在这种情况下,我希望应用程序等待空闲的会话可用。
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(); } }
在循环中调用睡眠通常会导致性能不佳。 例如:
while (true) { if (stream.available() > 0) { // read input } sleep(MILLISECONDS); }
如果MILLISECONDS太大,那么这段代码将花费很长时间才能意识到input是可用的。
如果MILLISECONDS太小,那么这个代码将浪费大量的系统资源来检查尚未到达的input。
循环中sleep
其他用途通常也是有问题的。 通常有更好的方法。
如果是问题,我该怎么办?
发布代码,也许我们可以给你一个明智的答案。
编辑
海事组织,一个更好的方法来解决这个问题是使用一个ThreadPoolExecutor
。
像这样的东西:
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(); } } }
这将configuration执行程序以匹配您的代码当前的工作方式。 还有其他一些方法可以做到这一点。 请参阅上面的javadoc链接。
正如其他人所说,这取决于使用情况。 合法的使用将是一个程序,旨在每10秒做一件事(但不是那么重要,需要准确的时间)。 我们有很多这样的“实用程序应用程序”,每隔几分钟就会导入数据和其他类似的任务。 这是一个简单的方法来执行这些任务,我们通常会将睡眠间隔设置得非常低,并使用一个计数器,使程序保持响应,并可以轻松退出。
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(); }
如何/何时能成为循环睡眠的问题?
人们有时使用它来代替正确的同步方法(如等待/通知)。
如果是问题,我该怎么办?
取决于你在做什么。 虽然我很难想象这样做的情况是最好的,但我想这也是可能的。
你可以在这个主题上查看Sun的并发教程 。
我想我在循环中遇到了一个完全合法的sleep()
方法。
我们有服务器和客户端之间的单向连接。 所以当客户端想要实现与服务器的asynchronous通信时,他会向服务器发送消息,而不是定期轮询服务器的响应。 需要有一些超时间隔。
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
时间间隔