如何检索必须在另一个线程上计算的值
在很多情况下,线程 A 需要一个必须在线程 B 上计算的值。(最常见的是,B == EDT。)考虑这个示例:
String host;
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
host = JOptionPane.showInputDialog("Enter host name: ");
}
});
openConnection(host);
当然,这不会编译,因为不允许使用匿名内部类写入主机
。让它发挥作用的最简单、最干净的方法是什么?我在下面列出了我所知道的方法。
There are many cases where thread A requires a value that must be computed on thread B. (Most commonly, B == EDT.) Consider this example:
String host;
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
host = JOptionPane.showInputDialog("Enter host name: ");
}
});
openConnection(host);
Of course, this doesn't compile, because the anonymous inner class isn't allowed to write to host
. What's the simplest, cleanest way to get this to work? I've included the ways I know of below.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
否:
使用
Future;
可能还有Callable
和ExecutorService
。未来
基本上是您想要的内容的精确编程表达:对未来答案的承诺,以及在答案可用之前阻止的能力。 Future 还会自动为您包装并呈现整个复杂的潜在并发噩梦和复杂性,并将其分解为一些明确定义的异常。这是一件好事,因为它迫使您处理它们,而您自己的解决方案可能永远不会揭示它们,除非出现一些异常的、难以诊断的行为。对于您的具体情况,您可以在 SwingWorker 上构建 实现了
Future
。不要重复,请看一下这个SO问题。No:
Use a
Future<T>
and possiblyCallable<T>
and anExecutorService
. AFuture
is basically an exact programmatic expression of what you want: a promise of a future answer, and the ability to block until the answer is available. Future also automatically wraps and presents for you an entire, complicated farrago of potential concurrency nightmares and complexities into a few clearly defined exceptions. This is a good thing because it forces you to deal with them, when a roll-your-own solution would likely never reveal them except in some aberrant, difficult to diagnose behavior.For your specific case, you can probably build on a SwingWorker which implements
Future
. Rather than duplicate, please take a look at this SO question.详细:使用内部类
Verbose: Use an inner class
我建议创建一个类来处理此问题,示例如下:
我将通过使类抽象并使用泛型来允许返回任何类型的值来扩展此方法。
编辑:检查是否从 EventDispatchThread 运行。
I'll recommend to create a class to handle this, samples below:
I'll extend this approach by making the class abstract and using generics to allow any type of values to be return.
EDIT: Checks if running from the EventDispatchThread.
请注意:作者不喜欢这个答案,它只是对特定问题的“鼻子上”的答案。
如果您只是想等待最小程度地修改上面的代码,那么它有效,您正在处理内部类只能引用决赛的问题。创建一个命名内部类而不是匿名内部类,并在该类中创建一个 String 主机字段。将该实例传递给
invokeAndWait()
。但以我的愚见,这仍然很糟糕,并且远不如我上面引用的Future<>
方法。Please note: the author doesn't like this answer, it's just the "on the nose" answer to the specific question.
If you're only looking for a wait to minimally modify the above code so it works, you're dealing with the inner-class-can-only-refer-to-finals problem. Carve out a named inner class instead of an anonymous one and create a String host field in that class. Pass that instance to
invokeAndWait()
. But this is still icky, in my humble opinion, and far inferior to theFuture<>
approach I cited above.优雅的?使用原子变量
Elegant? Use an atomic variable
技巧:使用数组
Hack: Use an array