在我下载最新版本的Netbeans之前,我从未想过使用Thread.Sleep。 Netbeans现在警告你不要使用Thread.Sleep。所以我对这个主题进行了一些研究,发现人们说你只需要使用Thread.Sleep进行调试/测试,如果你在任何时候使用它,那么你的代码写得很差。
所以我的问题是如何在以下情况下继续使用Thread.Sleep。
我编写了一个与另一个应用程序连接的服务器应用程序。服务器有两个线程:
处理来自套接字的数据并发送回其他信息或仅发送简单的信息。
这是主线程。在开始套接字线程后,它将进入无限循环。在这个while循环中,我检查以确保套接字线程仍处于活动状态,并且用户没有要求通过TrayIcon接口退出应用程序。然后我睡觉并继续循环。
使用此应用程序,TrayIcon是唯一的UI。
以下是我引用的代码段:
// 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();
}
}
答案 0 :(得分:6)
在大多数情况下,'首选'方法是使用JavaSE中内置的ScheduledExecutorService
来执行周期性任务,而不是每次使用while循环和Thread.Sleep()
时自己重新实现它。
你的例子本身并没有错。从Java 5开始,该语言现在具有更强大的支持。
答案 1 :(得分:3)
而不是你的Thread.sleep(3000)做:
getPrimaryThread().join(3000)
这将等待线程退出3秒钟。
答案 2 :(得分:2)
您应该考虑将事件监听器附加到托盘图标而不是轮询其状态。这样,您不需要额外的线程来监控。
如果由于某种原因你不能这样做,你仍然可以取消额外的线程,因为Timer
类可以等你。
答案 3 :(得分:1)
你似乎是偏执的,某些条件(可能是RuntimeException或Error?)会导致你的套接字线程死掉。理想情况下,您可以设计您的套接字线程,以保护自己免受崩溃。以下示例创建一个只能因JVM错误或线程中断而中断的循环:
public void run() {
while(!Thread.currentThread.isInterrupted()) {
try {
//you application logic
} catch (RuntimeException e) {
//log uncaught exception
}
}
}
为了关闭应用程序,你可以将一个监听器附加到包含对SocketThread的引用的TrayIcon,并且可以通过简单地中断它来阻止它。
socketThread.interrupt();
我将留下如何将ActionListener添加到TrayIcon中。