有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何避免使用线程。睡觉

我从不使用线。在我下载最新版本的Netbeans之前,我一直在思考睡眠问题。Netbeans现在警告您不要使用线程。睡觉所以我做了一些关于这个主题的研究,发现有人说你只需要使用线程。睡眠是为了调试/测试的目的,如果你在其他任何时候使用睡眠,你的代码写得很糟糕

所以我的问题是如何避免使用线程。在下列情况下睡觉

我已经编写了一个与另一个应用程序接口的服务器应用程序。服务器有两个线程:

  1. 处理来自socket的数据并发回其他信息或普通确认

  2. 这是主线。在启动socket线程之后,它将进入一个不确定的while循环。在这个while循环中,我检查以确保socket线程仍然处于活动状态,并且用户没有通过TrayIcon接口请求退出应用程序。然后我睡觉,继续这个while循环

在这个应用程序中,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();
    }
}

共 (4) 个答案

  1. # 1 楼答案

    而不是你的线。睡眠(3000)做:

    getPrimaryThread().join(3000)
    

    这将等待线程退出3秒钟

  2. # 2 楼答案

    您应该考虑将事件侦听器附加到托盘图标,而不是轮询其状态。这样你就不需要一个额外的线程来监视

    如果由于某种原因不能这样做,仍然可以删除额外的线程,因为^{}类可以完成等待您的任务

  3. # 3 楼答案

    在大多数情况下,“首选”方法是使用JavaSE中内置的ScheduledExecutorService来执行周期性任务,而不是每次使用while循环和Thread.Sleep()自己重新实现它

    你的例子本身没有错。从Java5开始,这门语言就有了更强大的支持

  4. # 4 楼答案

    您似乎对某些情况(可能是运行时异常或错误?)心存疑虑会导致你的插座线死掉。理想情况下,你应该设计你的套接字线程,这样它就可以保护自己不崩溃。以下示例创建了一个循环,该循环只能因JVM错误或线程中断而中断:

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

    为了关闭应用程序,您需要将一个侦听器附加到TrayIcon,该TrayIcon包含对SocketThread的引用,并且可以通过简单地中断它来停止它

    socketThread.interrupt();
    

    我将把如何将ActionListener添加到TrayIcon留给您来决定