检查2个线程之间的Internet连接+通信的可用性

时间:2011-08-24 22:36:03

标签: java multithreading swing htmlunit internet-connection

我有两个问题:

  1. 如何检查互联网连接是打开还是关闭?我正在使用Html Unit,而我正在使用Windows。

  2. 我想制作一个JLabel,说明我的JFrame中的互联网连接的可用性。类似的东西:

  3. while(true)
    {
        if(isOnline()) label.setText("online");
        else label.setText("offline");
    }
    

    但我认为我需要2个备份线程,但是我怎样才能创建这2个线程并在它们之间进行通信并实现此目的呢?

2 个答案:

答案 0 :(得分:2)

这里回答了类似的问题:how-to-check-if-internet-connection-is-present-in-java

要做你问题的第二部分,我想你可以调用java.util.Timer中的InetAddress.isReachable方法,该方法包含在SwingWorker线程中以定期轮询连接。

答案 1 :(得分:2)

while (true)对你的资源有点苛刻,应该暂停~10s。这并不像需要像股票价格股票那样准确和实时。

使用Swing,规则是不对事件分派线程花费时间。后台任务或其他长时间运行的操作永远不应该在它上面运行。

对于您的特定情况this适用:

  

必须根据非AWT事件更新GUI的程序:

     

例如,假设服务器程序可以从可能在不同计算机上运行的其他程序获取请求。这些请求可以随时出现,并且它们导致在某个可能未知的线程中调用服务器的一个方法。该方法如何更新GUI?通过在事件派发线程中执行GUI更新代码。

所以我要做的是设置一个计划任务,每隔10秒检查一次互联网连接的可用性关闭事件发送线程 - 这可能是你最好立即设置的main方法。另一方面,GUI的更新应该发生在 on 事件派发线程上。以下是Runnable的提案,可以对您的标签进行更新。我稍后会解释ConnectionChecker。我们使用ExecutorService执行它并将超时设置为5秒。如果ConnectionChecker在5秒内成功,则表示您已连接,否则您不是。然后,此结果用于使用JLabel更新事件派发线程中的SwingUtilities#invokeLater

public static class Updater implements Runnable {
    private final JLabel label;
    private final ExecutorService executor;
     /* constructor left out */
    public void run() {
        boolean connected = false;
        Future<?> connHandle = executor.submit(new ConnectionChecker());
        try {
            connHandle.get(5, TimeUnit.SECONDS);
            connected = true;
        } catch (TimeOutException ex) {
            /* connected = false; */
        }
        catch (InterruptedException ex) {
            /* Let it be handled higher elsewhere */
            Thread.currentThread().interrupt();
        } catch (CancellationException ex) {
            /* happens only if you actively cancel the Future */
        } catch (ExecutionException ex) {
            /* connected = false */
        }

        final boolean result = connected;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if (result)
                    label.setText("online");
                else
                    label.setText("offline");
            }
        });
    }
}

现在我们必须在main方法中设置一个定期执行的Updater,我们还创建了JLabel和ExecutorService:

public static void main(String... args) {
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    JLabel label = ...;
    Updater updater = new Updater(label, executor);
    executor.scheduleAtFixedRate(updater, 0, 10, TimeUnit.SECONDS);
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            //GUI initialization code
        }
    });
}

最后,让我们理解ConnectionChecker。你有很多方法可以做到这一点。一个快速而肮脏的解决方案是简单地获取可能在未来几年内保留的网页 - www.google.com如何。如果您已连接到Internet(正确),则此查询将成功。否则,它最终会抛出一些异常。通过连接,下载应在5秒内完成 - 如果不是,则可以安全地连接尝试超时。无论哪种方式,如果下载未及时成功,您将在Updater中收到异常。使用简单的URLConnection或类似内容进行下载。