2

在我的程序中,我实际上是在尝试连接到发布者并获取数据。这些步骤中有基本功能

  1. 我使用用户名和密码等与发布者建立连接
  2. 我提出数据请求。方法退出
  3. 发布者的 API 给了我一个方法的回调onDataUpdate(Object theUpdate)

从那里,我可以打印数据,或将其写入数据库或我需要做的任何事情。这一切都有效。

我的问题是,我现在想以这样一种方式包装功能,即调用程序可以说请求数据并在我拥有它时立即接收它。意思是,我希望我暴露的方法看起来像

public Object getData() {
    subscribeForData();
    // somehow wait
    return theUpdate;    
}

我怎样才能做到这一点?当我收到更新时,有什么方法可以使用线程等待/通知?我是 stackoverflow 和多线程编程的新手,因此非常感谢任何帮助和示例代码!提前致谢。

4

5 回答 5

1

在这种情况下,我更喜欢使用CountDownLatch,我将在lathch订阅发布者后立即使用 count 1 初始化我将调用await() latch,当我收到回调时,我将countdown使用latch.

于 2012-07-03T18:16:37.283 回答
0

使用同步队列。在getData中创建,在回调方法中调用put(),然后在getData()结束时在原线程中调用take()。

于 2012-07-03T18:12:06.557 回答
0

查看 CompletionService,尤其是ExecutorCompletionServiceJava Concurrency in Practice一书中有一个很好的网页加载器/渲染器示例。

于 2012-07-03T18:13:22.847 回答
0

我不完全确定你的问题,但我会试一试 - 希望它有所帮助:)

为此,您可以在java中使用阻塞队列(生产者消费者消息)-如果您在调用回调时写入队列-从另一个线程中,您可以从队列中读取。阻塞队列是线程安全的(但可能不符合您的要求)。

如果您只有一个线程写入集合并且可能有多个读取器(甚至只是读取器),您还可以查看读写锁。

您还可以查看观察者模式 - 供参考:http ://www.vogella.com/articles/DesignPatternObserver/article.html

如果这些都不起作用,可以考虑使用来自 VM 内消息传递服务器的队列/主题,例如 ZeroMQ/ActiveMQ 或 Redis/HazelCast 之类的东西。

希望它有帮助,祝你好运

于 2012-07-03T18:19:50.233 回答
0

将异步调用转换为同步调用是一项有趣的练习,我经常在面试中使用它(反之亦然,将同步调用包装在异步中)。

所以有一个requestData方法会立即返回,它(或其他东西)稍后会onDataUpdate不同的线程中调用。您想创建一个新方法,例如requestDataSynchronous不需要调用者使用回调而是阻塞直到数据可用并将其返回给调用者。

所以你需要requestDataSynchronous做的是:

  1. 称呼requestData
  2. 等待直到onDataUpdate被调用(在不同的线程中)
  3. onDataUpdate获取收到的数据
  4. 将其返回给调用者

其中,#2 和#3 必须通过某种模式的线程间通信来完成。您可以使用wait/notifiy但使用BlockingQueue可能要简单得多。onDataUpdate一旦数据可用就写入它,并requestDataSynchronous从中读取,阻塞读取直到onDataUpdate写入它。

使用ExecutorService可能会使这更容易,但知道发生了什么会很有用。

于 2012-07-03T18:35:55.280 回答