Java 检查互联网连接的可用性+;在两个线程之间通信
我有两个问题:Java 检查互联网连接的可用性+;在两个线程之间通信,java,multithreading,swing,htmlunit,internet-connection,Java,Multithreading,Swing,Htmlunit,Internet Connection,我有两个问题: 如何检查Internet连接是否已打开或关闭?我用的是Html单元,我用的是Windows 我想制作一个JLabel,在我的JFrame中声明internet连接的可用性。比如: 但是我想我需要两个专用线程,但是我如何才能创建这两个线程并在它们之间进行通信并实现这一点呢?这里回答了一个类似的问题: 要完成问题的第二部分,我想您可以调用包装在SwingWorker线程中的java.util.Timer中的方法来定期轮询连接。虽然(true)对您的资源有点苛刻,但应该暂停约10秒。
但是我想我需要两个专用线程,但是我如何才能创建这两个线程并在它们之间进行通信并实现这一点呢?这里回答了一个类似的问题: 要完成问题的第二部分,我想您可以调用包装在SwingWorker线程中的java.util.Timer中的方法来定期轮询连接。
虽然(true)
对您的资源有点苛刻,但应该暂停约10秒。这并不是说,它需要像股票行情一样准确和实时
对于Swing,规则是不做任何在事件分派线程上花费时间的事情。后台任务或其他长时间运行的操作不应在其上运行
适用于您的特定情况:
非AWT事件导致GUI必须更新的程序:
例如,假设一个服务器程序可以从可能在不同机器上运行的其他程序获取请求。这些请求可以在任何时候出现,它们导致服务器的一个方法在某个可能未知的线程中被调用。该方法如何更新GUI?通过在事件调度线程中执行GUI更新代码
因此,我要做的是设置一个计划任务,每10秒检查一次internet连接的可用性关闭事件调度线程-这可能是最好立即在main
方法中设置的。另一方面,GUI的更新应该在事件调度线程上进行。下面是一个Runnable
的建议,它可以在标签上进行更新。稍后我将解释连接检查程序。我们使用ExecutorService
执行它,并将超时设置为5秒。如果ConnectionChecker
在5秒内成功,则表示您已连接,否则不连接。然后,此结果用于使用SwingUtilities\invokeLater
更新事件调度线程上的JLabel
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");
}
});
}
}
最后,让我们来分析一下连接检查器。有很多方法可以做到这一点。一个快速而肮脏的解决方案是简单地获取一个可能在未来几年内保留的网页——www.google.com怎么样。如果您连接到Internet(正确),此查询将成功。否则,它将最终抛出一些异常。有了连接,下载应该在5秒钟内完成——如果没有,则可以安全地暂停连接尝试。无论哪种方式,如果下载未及时成功,您将在更新程序中收到异常。使用一个简单的URLConnection
或类似的方法进行下载。您能提供一个简单的java.util.Timer示例,该示例包装在SwingWorker线程中。
?:)@这将是另一个关于2.nd thread too+1+1的详细答案的建议,但是没有这样的构造函数Updater(label,executor)
谢谢!我省略了它以缩短示例:/*构造函数省略了*/
。您必须手动添加它-它是更新程序(JLabel标签,ExecutorService executor),然后设置实例变量。ok修复了这个问题。ConnectionChecker()
它是什么样子的呢?我以前没有使用过ExecutorService
和Future
。谢谢:)它实现了Runnable,run
方法应该看起来和气垫船链接的代码完全一样。好吧,它可以工作,但我总是得到TimeOutException
,并且从不通过connHandle.get(10,TimeUnit.SECONDS)代码>
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");
}
});
}
}
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
}
});
}